Product Decisions This Supports
- Developer Productivity: Accelerates Laravel/PHP development by enabling reusable, composable macros for Eloquent models, collections, and other core components—reducing boilerplate and standardizing patterns across the codebase.
- Consistent API Design: Facilitates a unified, macro-based approach to extending Laravel’s functionality, ensuring team alignment and reducing technical debt from ad-hoc extensions.
- Rapid Prototyping: Speeds up MVP development by allowing PMs to define domain-specific behaviors (e.g.,
User::macro('isPremium', fn() => ...)) without waiting for full feature implementation.
- Build vs. Buy Tradeoff: Justifies building custom Laravel extensions in-house (vs. third-party packages) when macros align with unique business logic (e.g., audit trails, soft deletes with custom rules).
- Roadmap Prioritization: Enables PMs to deprioritize generic package dependencies in favor of lightweight, internally controlled extensions (e.g., replacing
spatie/laravel-activitylog with a macro for audit trails).
- Microservices/Modularity: Supports modular monoliths or microservices by encapsulating domain logic in macros (e.g.,
Order::macro('calculateTax', ...)) for reusable business rules.
When to Consider This Package
-
Adopt if:
- Your team frequently extends Laravel’s core (Eloquent, Collections, Blade) with repetitive logic.
- You prioritize internal control over third-party dependencies for critical functionality.
- Your roadmap includes domain-specific behaviors (e.g., custom validation, query scopes) that could be standardized via macros.
- You’re migrating legacy code to Laravel and need a lightweight, maintainable way to backfill extensions.
- Your stack is PHP/Laravel-heavy, and you’re comfortable with PHP 8+ features (closures, attributes).
-
Look elsewhere if:
- You need pre-built, battle-tested features (e.g., OAuth, payments) → Use dedicated packages (e.g.,
laravel/socialite, spatie/laravel-payments).
- Your team lacks PHP/Laravel expertise to safely extend core classes with macros.
- You’re constrained by legacy Laravel versions (<8.0) where macro support is limited.
- The use case is UI-heavy (e.g., frontend components) → Consider Blade directives or Alpine.js instead.
- Compliance/audit requirements mandate vendor-supported solutions over internal macros.
How to Pitch It (Stakeholders)
For Executives:
"This package lets us write once, reuse everywhere in Laravel—like ‘copy-paste on steroids’ for our developers. Instead of reinventing the wheel for common logic (e.g., ‘is this user active?’ or ‘calculate this discount’), we can define it once as a macro and use it across the app. This cuts development time by 20–30% on repetitive tasks, reduces bugs from duplicated code, and keeps us in control of our tech stack without bloating it with third-party dependencies. Think of it as Lego blocks for Laravel: snap together domain logic faster, with zero vendor lock-in."
ROI Hook:
"For every 10 lines of macro-defined logic, we save 30+ hours of dev time annually—with zero ongoing costs. It’s a force multiplier for our roadmap."
For Engineering Leaders:
*"Macroable gives us a scalable, maintainable way to extend Laravel’s core without forking or hacking. Key wins:
- No more ‘magic’ in the codebase: Replace
if ($user->role == 'admin') with if ($user->isAdmin())—self-documenting and testable.
- Team alignment: Standardize how we add query scopes, validation, or business rules. No more ‘works on my machine’ for custom extensions.
- Future-proof: Macros survive Laravel upgrades (unlike some package integrations).
- Performance: Zero runtime overhead—macros are compiled into the class at load time.
Tradeoffs:
- Requires discipline to avoid macro sprawl (we’ll enforce a naming convention and review process).
- Not a silver bullet for complex features (e.g., replace
spatie/laravel-permission with macros only if your RBAC is trivial).
Ask: Can we pilot this for 2–3 high-impact extensions (e.g., audit trails, discount calculations) and measure dev time saved?"*
For Developers:
*"This is PHP’s answer to Ruby’s extend or JavaScript’s mixins—but built into Laravel. Here’s how it changes your workflow:
- Eloquent Models: Add
User::macro('isPremium', fn() => $this->subscriptions->where('active', true)->exists()) and use $user->isPremium anywhere.
- Collections:
Collection::macro('groupByMonth', fn() => $this->groupBy(fn($item) => $item->created_at->format('Y-m'))).
- Blade: Extend directives with
Blade::macro('alert', fn($type, $message) => ...).
- Testing: Mock macros like any other method—no need for complex stubs.
Why it’s better than packages:
- No dependencies: MIT-licensed, zero bloat.
- No config: Just drop it in
composer.json and start macroing.
- IDE-friendly: Autocomplete and type hints work out of the box.
Let’s macro-ize [X, Y, Z] first—I’ll show you how it cuts our User model from 200 to 50 lines."*