Laravel Macros, Mixins &amp; Custom Collections | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://msaied.com) - [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [About](https://msaied.com#about)

           [  Contact](https://msaied.com#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://msaied.com)
- [ProjectsCase studies](https://msaied.com/projects)
- [ArticlesEngineering notes](https://msaied.com/articles)
- [CertificatesCredentials](https://msaied.com/certificates)
- [AboutHow I work](https://msaied.com#about)
- [ContactGet in touch](https://msaied.com#contact)

  [Start a conversation](https://msaied.com#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://msaied.com)
2. /
3. [Articles](https://msaied.com/articles)
4. /
5. Macros, Mixins, and Custom Collection Methods in Laravel

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

 Learn how to extend Laravel's core classes with macros, mixins, and custom Collection methods — keeping your codebase expressive without forking the framework.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://msaied.com#person) Published 5 Jul 2026 · Updated 5 Jul 2026 · 3 min read

ShareCopy linkCopied

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

  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
--------------------------------------------------------

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.

- [laravel](https://msaied.com/articles?search=laravel)
- [collections](https://msaied.com/articles?search=collections)
- [macros](https://msaied.com/articles?search=macros)
- [php](https://msaied.com/articles?search=php)

 Frequently asked questions 
---------------------------

  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.

   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.

   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.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

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

[About](https://msaied.com#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleFilament at Scale: Multi-Panel Auth, Custom Panels, and Table Query Tuning](https://msaied.com/articles/filament-at-scale-multi-panel-auth-custom-panels-and-table-query-tuning-2) [Next articlePostgreSQL Partial and Covering Indexes in Laravel Migrations and Query Plans](https://msaied.com/articles/postgresql-partial-and-covering-indexes-in-laravel-migrations-and-query-plans)  

   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)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://msaied.com#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/739/2d6897fdcdcf090613f96f72a64b8a78.png)  · 4 min read### MySQL Full-Text Search in Laravel: Indexes, Relevance Scoring, and Boolean Mode

4 Oct 2026 ](https://msaied.com/articles/mysql-full-text-search-in-laravel-indexes-relevance-scoring-and-boolean-mode) [ ![](https://cdn.msaied.com/738/073696a3fefe18bec825beec5ac658f5.png)  · 4 min read### Laravel Queue Rate-Limited Middleware: Throttling Jobs Without Losing Work

4 Oct 2026 ](https://msaied.com/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) [ ![](https://cdn.msaied.com/737/f5c7e78a645325d4cff8d43f2835f136.png)  · 4 min read### Laravel Telescope Alternatives: Structured Observability with Pulse, Debugbar, and Custom Watchers

4 Oct 2026 ](https://msaied.com/articles/laravel-telescope-alternatives-structured-observability-with-pulse-debugbar-and-custom-watchers) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://msaied.com#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://msaied.com)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://msaied.com/sitemap.xml)
