Laravel Macros, Mixins &amp; Custom Collections | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Macros, Mixins, and Custom Collection Methods in Laravel        On this page       1. [  Macros, Mixins, and Custom Collection Methods in Laravel ](#macros-mixins-and-custom-collection-methods-in-laravel)
2. [  How Macroable Works ](#how-codemacroablecode-works)
3. [  Grouping with Mixins ](#grouping-with-mixins)
4. [  Extending Request and Response ](#extending-request-and-response)
5. [  Testing Macros ](#testing-macros)
6. [  When Not to Use Macros ](#when-not-to-use-macros)
7. [  Takeaways ](#takeaways)

  ![Macros, Mixins, and Custom Collection Methods in Laravel](https://cdn.msaied.com/372/b8e39b17d427358aa43b5c3e8c1be908.png)

  #laravel   #collections   #macros   #php  

 Macros, Mixins, and Custom Collection Methods in Laravel 
==========================================================

     5 Jul 2026      3 min read    ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said  

       Table of contents

1. [  01   Macros, Mixins, and Custom Collection Methods in Laravel  ](#macros-mixins-and-custom-collection-methods-in-laravel)
2. [  02   How Macroable Works  ](#how-codemacroablecode-works)
3. [  03   Grouping with Mixins  ](#grouping-with-mixins)
4. [  04   Extending Request and Response  ](#extending-request-and-response)
5. [  05   Testing Macros  ](#testing-macros)
6. [  06   When Not to Use Macros  ](#when-not-to-use-macros)
7. [  07   Takeaways  ](#takeaways)

 Macros, Mixins, and Custom Collection Methods in Laravel
--------------------------------------------------------

Laravel's `Macroable` trait is one of the most underused extension points in the framework. Rather than subclassing `Collection`, `Request`, or `Response`, you can bolt on behaviour at boot time — keeping the framework's internals intact while making your application code read like a DSL.

### How `Macroable` Works

Any class using the `Macroable` trait gains two static methods: `macro()` and `mixin()`. When you call a macro, Laravel resolves it from a static array and invokes it bound to the current instance — so `$this` works exactly as you'd expect.

```php
use Illuminate\Support\Collection;

Collection::macro('toIndexedMap', function (string $key): array {
    return $this->keyBy($key)->map->toArray()->all();
});

// Usage
$users = collect([
    ['id' => 1, 'name' => 'Alice'],
    ['id' => 2, 'name' => 'Bob'],
]);

$map = $users->toIndexedMap('id');
// [1 => ['id' => 1, 'name' => 'Alice'], 2 => [...]]

```

Register macros inside a service provider's `boot()` method so they're available for the entire request lifecycle.

### Grouping with Mixins

Once you have more than a handful of macros, a mixin class keeps things tidy. A mixin is a plain class whose public methods each return a `Closure`. Laravel iterates those methods and registers each one as a macro.

```php
namespace App\Support\Mixins;

use Illuminate\Support\Collection;

class CollectionMixin
{
    public function paginateArray(): \Closure
    {
        return function (int $perPage, int $page = 1): array {
            return [
                'data'  => $this->forPage($page, $perPage)->values()->all(),
                'total' => $this->count(),
                'page'  => $page,
                'pages' => (int) ceil($this->count() / $perPage),
            ];
        };
    }

    public function mapToValueObjects(): \Closure
    {
        return function (string $class): static {
            return $this->map(fn ($item) => new $class($item));
        };
    }
}

```

```php
// AppServiceProvider::boot()
Collection::mixin(new \App\Support\Mixins\CollectionMixin());

```

IDE support is the usual concern. Add a `@mixin` annotation in a stub or use a package like `barryvdh/laravel-ide-helper` to generate PHPDoc for macros.

### Extending Request and Response

The same pattern applies beyond `Collection`. Extending `Request` is especially useful for multi-tenant apps where you repeatedly resolve the current tenant.

```php
use Illuminate\Http\Request;

Request::macro('tenant', function (): ?\App\Models\Tenant {
    return $this->attributes->get('tenant');
});

// In a middleware
$request->attributes->set('tenant', $resolvedTenant);

// In a controller
$tenant = $request->tenant();

```

No inheritance, no custom `FormRequest` base class — just a clean extension point registered once.

### Testing Macros

Because macros are registered globally, test them in isolation by calling the macro directly in a unit test. Pest makes this concise:

```php
use Illuminate\Support\Collection;

it('paginates an array correctly', function () {
    $result = collect(range(1, 25))->paginateArray(perPage: 10, page: 2);

    expect($result['data'])->toHaveCount(10)
        ->and($result['total'])->toBe(25)
        ->and($result['pages'])->toBe(3);
});

```

Register the mixin in a `beforeEach` or in a dedicated `TestCase` base if it isn't already booted by the application.

### When Not to Use Macros

- **Complex domain logic** — a dedicated service or action class is more testable and discoverable.
- **Overriding existing methods** — macros cannot override methods already defined on the class; they only add new ones.
- **Cross-cutting concerns with dependencies** — if your macro needs injected services, resolve them from the container inside the closure rather than relying on constructor injection.

### Takeaways

- Register macros in service provider `boot()` methods, never in `register()`.
- Use mixin classes to group related macros and keep providers lean.
- `$this` inside a macro closure is bound to the instance — use it freely.
- Add IDE stubs or `@mixin` annotations so static analysis tools stay happy.
- Prefer macros for *presentation and convenience* helpers; keep domain logic in dedicated classes.

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Fmacros-mixins-and-custom-collection-methods-in-laravel-1&text=Macros%2C+Mixins%2C+and+Custom+Collection+Methods+in+Laravel) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Fmacros-mixins-and-custom-collection-methods-in-laravel-1) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  Can a macro override an existing method on a Laravel class?        No. The `Macroable` trait only adds new methods. If a method already exists on the class, the macro is silently ignored. Use subclassing or decoration if you need to override existing behaviour. 

      Q02  How do I get IDE autocompletion for registered macros?        Add a `@mixin` PHPDoc annotation pointing to your mixin class, or use `barryvdh/laravel-ide-helper` which can generate `_ide_helper.php` stubs that include macro signatures for tools like PhpStorm. 

      Q03  Is there a performance cost to registering many macros?        Negligible. Macros are stored in a static array and resolved with a simple `isset` check. The cost is one closure allocation per macro at boot time, which is trivial compared to typical service container bindings. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![Domain-Driven Design in Laravel: Value Objects, DTOs, and Actions Without Bloat](https://cdn.msaied.com/377/b5c2aef77aed51ee8694f377085af424.png) laravel ddd architecture 

### Domain-Driven Design in Laravel: Value Objects, DTOs, and Actions Without Bloat

Learn how to model domain concepts with value objects, DTOs, and single-action classes in Laravel — keeping yo...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 6 Jul 2026     4 min read  

  Read    

 ](https://msaied.com/articles/domain-driven-design-in-laravel-value-objects-dtos-and-actions-without-bloat) [ ![What's Missing from Your PHP Development Environment: Meet DDLess](https://cdn.msaied.com/379/baa8990d4c7b46d18498d69d68f9b6d2.png) DDLess PHP Debugging Laravel Tools 

### What's Missing from Your PHP Development Environment: Meet DDLess

DDLess is a PHP development workbench that brings step debugging, an in-breakpoint playground, and an interact...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 6 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/whats-missing-from-your-php-development-environment-meet-ddless) [ ![CQRS in Laravel Without a Framework: Commands, Handlers, and Query Objects](https://cdn.msaied.com/376/bec9da4b7a7ddeee26dac3df6f5d6c44.png) laravel cqrs architecture 

### CQRS in Laravel Without a Framework: Commands, Handlers, and Query Objects

Skip the heavy CQRS libraries. Learn how to implement commands, command handlers, and query objects in plain L...

  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MJ.jpg)  Mohamed Said 

 6 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/cqrs-in-laravel-without-a-framework-commands-handlers-and-query-objects) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
