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)    Laravel Macros, Mixins, and Custom Collection Methods That Actually Ship        On this page       1. [  Why Macros Deserve More Respect ](#why-macros-deserve-more-respect)
2. [  Pattern 1 — Targeted Macros in Focused Providers ](#pattern-1-targeted-macros-in-focused-providers)
3. [  Octane Safety ](#octane-safety)
4. [  Pattern 2 — Mixins for Cohesive Method Groups ](#pattern-2-mixins-for-cohesive-method-groups)
5. [  Pattern 3 — Typed Collection Subclasses (The Underused One) ](#pattern-3-typed-collection-subclasses-the-underused-one)
6. [  Testing Your Macros ](#testing-your-macros)
7. [  Takeaways ](#takeaways)

  ![Laravel Macros, Mixins, and Custom Collection Methods That Actually Ship](https://cdn.msaied.com/442/b239b69e5a334711c8b4ca8804556c64.png)

  #laravel   #macros   #collections   #php  

 Laravel Macros, Mixins, and Custom Collection Methods That Actually Ship 
==========================================================================

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

       Table of contents

1. [  01   Why Macros Deserve More Respect  ](#why-macros-deserve-more-respect)
2. [  02   Pattern 1 — Targeted Macros in Focused Providers  ](#pattern-1-targeted-macros-in-focused-providers)
3. [  03   Octane Safety  ](#octane-safety)
4. [  04   Pattern 2 — Mixins for Cohesive Method Groups  ](#pattern-2-mixins-for-cohesive-method-groups)
5. [  05   Pattern 3 — Typed Collection Subclasses (The Underused One)  ](#pattern-3-typed-collection-subclasses-the-underused-one)
6. [  06   Testing Your Macros  ](#testing-your-macros)
7. [  07   Takeaways  ](#takeaways)

 Why Macros Deserve More Respect
-------------------------------

Most teams discover `Macro` when they want a one-liner on `Str` or `Collection`. They drop it in `AppServiceProvider::boot`, ship it, and move on. That works — until you run under Octane, add PHPStan, or onboard a developer who has no idea where `->toAssocBy()` came from.

This article covers the three patterns that actually hold up in production: **targeted macros**, **mixins**, and **typed Collection subclasses**.

---

Pattern 1 — Targeted Macros in Focused Providers
------------------------------------------------

Registering every macro in `AppServiceProvider` creates a god-provider. Instead, create a dedicated provider per domain.

```php
// app/Providers/CollectionMacroServiceProvider.php
class CollectionMacroServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Collection::macro('toAssocBy', function (string $key): Collection {
            /** @var Collection $this */
            return $this->keyBy($key);
        });

        Collection::macro('filterMap', function (Closure $callback): Collection {
            /** @var Collection $this */
            return $this->map($callback)->filter()->values();
        });
    }
}

```

Register it in `bootstrap/providers.php` (Laravel 11+) or `config/app.php`. The provider is small, testable, and easy to grep.

### Octane Safety

Macros are stored in a static `$macros` array on the `Macroable` trait. Under Octane the worker boots once, so macros registered in `boot()` persist across requests — that is exactly what you want. The danger is re-registering inside a request lifecycle (e.g., inside a Livewire component). Keep macro registration in providers only.

---

Pattern 2 — Mixins for Cohesive Method Groups
---------------------------------------------

A mixin is a plain class whose public methods become macros in bulk. Use it when you have five or more related methods.

```php
// app/Support/CollectionDateMixin.php
/**
 * @mixin \Illuminate\Support\Collection
 */
class CollectionDateMixin
{
    public function betweenDates(): Closure
    {
        return function (string $field, Carbon $from, Carbon $to): Collection {
            /** @var Collection $this */
            return $this->filter(
                fn ($item) => data_get($item, $field) >= $from
                    && data_get($item, $field) values();
        };
    }

    public function latestBy(): Closure
    {
        return function (string $field): mixed {
            /** @var Collection $this */
            return $this->sortByDesc($field)->first();
        };
    }
}

```

```php
// In your provider
Collection::mixin(new CollectionDateMixin());

```

The `@mixin` docblock is picked up by **Laravel IDE Helper** and **PHPStan** (with the `larastan/larastan` extension), giving you autocompletion and type inference without extra stubs.

---

Pattern 3 — Typed Collection Subclasses (The Underused One)
-----------------------------------------------------------

For domain-specific collections, a subclass beats a macro every time. You get real return types, no `@var` hacks, and Eloquent integrates natively.

```php
// app/Domain/Billing/InvoiceCollection.php
/**
 * @extends Collection
 */
class InvoiceCollection extends Collection
{
    public function totalOwed(): Money
    {
        return $this->reduce(
            fn (Money $carry, Invoice $invoice) => $carry->add($invoice->amount),
            Money::of(0, 'GBP')
        );
    }

    public function overdue(): static
    {
        return $this->filter(
            fn (Invoice $i) => $i->due_at->isPast() && ! $i->paid
        )->values();
    }
}

```

Tell Eloquent to use it:

```php
// app/Models/Invoice.php
class Invoice extends Model
{
    public function newCollection(array $models = []): InvoiceCollection
    {
        return new InvoiceCollection($models);
    }
}

```

Now `Invoice::all()` returns `InvoiceCollection`, and PHPStan knows it.

---

Testing Your Macros
-------------------

```php
// tests/Unit/CollectionMacroTest.php
it('filterMap removes null results', function () {
    $result = collect([1, 2, 3, 4])
        ->filterMap(fn ($n) => $n % 2 === 0 ? $n * 10 : null);

    expect($result->values()->all())->toBe([20, 40]);
});

```

Unit-test macros in isolation — no HTTP, no database. Fast feedback, easy CI.

---

Takeaways
---------

- Register macros in **dedicated providers**, never inside request-scoped code.
- Use **mixins** when you have a cohesive group of five or more methods; the `@mixin` docblock unlocks IDE and static analysis support.
- Prefer **typed Collection subclasses** for domain models — they give real generics, no magic strings, and Eloquent wires them up automatically.
- Macros survive Octane restarts because they live in static state bootstrapped once per worker.
- Always write a unit test per macro; they are trivial to test and painful to debug silently broken.

 Found this useful?

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

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

  3 questions  

     Q01  Are Laravel macros safe to use under Octane?        Yes, as long as you register them in a service provider's boot() method. Macros are stored in static arrays that persist for the worker's lifetime, which is exactly what you want. Never register macros inside request-scoped code like controllers or Livewire components. 

      Q02  When should I use a mixin versus a typed Collection subclass?        Use a mixin when you want to add utility methods to the base Collection class for general use across the app. Use a typed subclass when the collection belongs to a specific domain model — you get real generic type hints, PHPStan support, and Eloquent integration via newCollection(). 

      Q03  How do I get PHPStan to recognise custom macros?        Add the @mixin docblock to your mixin class and ensure larastan/larastan is installed. For standalone macros, you can write a PHPStan extension or use IDE Helper's generated _ide_helper.php, which larastan reads automatically. 

  Continue reading

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

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

 [ ![Laravel + Python FastAPI: Image OCR Demo](https://cdn.msaied.com/447/5f3d87146fbf19957973cbc88c6c0155.png) Laravel Python FastAPI 

### Laravel + Python FastAPI: Image OCR Demo

Learn how to call a Python image OCR script from Laravel using FastAPI as the bridge. This premium tutorial wa...

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

 20 Jul 2026     3 min read  

  Read    

 ](https://msaied.com/articles/laravel-python-fastapi-image-ocr-demo) [ ![CQRS in Laravel Without a Framework: Commands, Handlers, and Read Models That Stay Lean](https://cdn.msaied.com/446/a05febe70b72107387f210e0f9eae089.png) laravel cqrs architecture 

### CQRS in Laravel Without a Framework: Commands, Handlers, and Read Models That Stay Lean

Skip the heavy event-sourcing libraries. This guide shows how to implement a practical CQRS layer in Laravel u...

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

 20 Jul 2026     1 min read  

  Read    

 ](https://msaied.com/articles/cqrs-in-laravel-without-a-framework-commands-handlers-and-read-models-that-stay-lean) [ ![Laravel Event Sourcing: Projections, Snapshots, and Replay Without the Framework Tax](https://cdn.msaied.com/445/b4f83e0b5da7c11e2fe942eebc1cad08.png) laravel event-sourcing ddd 

### Laravel Event Sourcing: Projections, Snapshots, and Replay Without the Framework Tax

Event sourcing in Laravel without a heavy framework. Build lean projectors, snapshot aggregates at scale, and...

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

 19 Jul 2026     4 min read  

  Read    

 ](https://msaied.com/articles/laravel-event-sourcing-projections-snapshots-and-replay-without-the-framework-tax) 

   [  ![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)
