Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Str Mixins Laravel Package

revolution/laravel-str-mixins

Adds custom macro mixins to Laravel's Str helper, extending it with handy string methods you can call fluently anywhere. A lightweight way to register reusable string macros across your app without repeating helper code.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and verify registration before writing any application code.

composer require revolution/laravel-str-mixins
php artisan package:discover
php artisan optimize:clear

The package registers its closures against Illuminate\Support\Str (which is Macroable) from a service provider. Check vendor/revolution/laravel-str-mixins/composer.json for extra.laravel.providers. If it's listed, discovery handles everything. If not — common in micro-packages — add the provider to bootstrap/providers.php (Laravel 11+) or config/app.php (Laravel 10 and below) manually.

Where to look first, in order:

  1. vendor/revolution/laravel-str-mixins/src/ — the mixin class is the documentation. Every public function on it becomes a Str macro; the README will be thinner than the source. Read it end to end. At this size there is no excuse not to.
  2. composer.json — check the illuminate/support constraint against your pinned Laravel version. Small packages lag on major-version constraints even when the code is functionally compatible.
  3. Runtime check — trust tinker, not prose:
// php artisan tinker
Str::hasMacro('yourMethodName');                 // true once registered
array_keys((new ReflectionClass(Str::class))->getMethods());

First use case. The realistic value is repeated low-value text chores: deriving display labels, building initials for avatars, normalizing user input, trimming/cleaning identifiers, extracting segments. Pick one live call site, not a greenfield prototype:

use Illuminate\Support\Str;

$initials = Str::of($user->name)->squish()->explode(' ')->map(fn ($p) => Str::substr($p, 0, 1))->implode('');

Confirm the package method you planned to use actually exists and behaves as you expect on empty strings, multibyte input, and null before you spread it across the codebase.

Implementation Patterns

Wrap the sanctioned subset in an internal class. This is the single highest-leverage move. It converts an unvetted external dependency into an internal implementation detail, and makes the eventual vendoring decision a non-event:

namespace App\Support;

use Illuminate\Support\Str;

final class Text
{
    public static function initials(?string $name): string
    {
        return Str::of((string) $name)->squish()
            ->explode(' ')
            ->filter()
            ->map(fn ($part) => Str::substr($part, 0, 1))
            ->take(2)
            ->implode('');
    }
}

Application code calls Text::initials(), never the package directly. If you drop the dependency, you edit one file.

Chain through Str::of() / Stringable pipelines at boundaries. The mixins compose naturally with core methods, so use them in form request preparation, API resource formatting, and Eloquent accessors — places where a fluent pipeline reads better than three nested preg_replace calls:

protected function slug(): Attribute
{
    return Attribute::make(
        get: fn () => Str::of($this->title)->squish()->slug()->toString(),
    );
}

Register a Stringable macro when the transform is only used mid-chain. Str::macro() gives you a static call; Stringable::macro() gives you ->yourThing() and keeps pipelines fluent. Mixin registration on Str does not automatically give you the Stringable form in every case, so pick deliberately based on how you'll call it.

Contract tests per helper you consume. One test per method, asserting output for: normal input, empty string, null, multibyte/Unicode, and leading/trailing whitespace. These are what catch both silent macro collisions and framework shadowing on upgrade:

it('produces initials', function () {
    expect(Text::initials('Jane van Doe'))->toBe('JD');
    expect(Text::initials(''))->toBe('');
});

Add @method stubs in the same PR as adoption. PHPStan/Larastan and IDEs cannot resolve macros; without stubs you get CI false positives and IDE warnings, and the adoption stalls because developers blame the package. A small stub file or a larastan baseline entry is cheaper than the friction. Do not defer this.

Pilot in one non-critical service, then review after one Laravel minor upgrade. If, at review, the helpers serve only one or two call sites, close the pilot and inline the logic. The cost/benefit flips fast on micro-dependencies.

Gotchas and Tips

  • Macro registration is global and silent. Macroable::macro() overwrites without warning. A collision with another package or your own bootstrapping code is last-writer-wins — behavior changes, no exception. Detect with a boot-time assertion that captures the macro before/after registration, or simply rely on per-helper contract tests.
  • Framework shadowing on upgrade is the sneaky failure. Macros are only consulted when no real static method exists. If a Laravel minor release adds a same-named native method, the macro stops being invoked and semantics change with no test failure — unless you assert on output. Laravel has repeatedly absorbed popular community string helpers into Str/Stringable; audit the method inventory against your current version before adopting, not just at install.
  • Pin the exact version, not a caret range. Two stars, zero dependents, single author: there is no community canary. Treat upgrades as deliberate review events, not composer update churn, and put "re-validate string mixins" on the framework upgrade checklist.
  • Static analysis blind spots. PHPStan/Larastan, Psalm, and IDEs won't resolve the macro methods without stubs. Unmitigated, this degrades CI signal quality and can mask real defects — worse than the string bug you were trying to avoid.
  • Check Unicode and empty-string semantics in the source before trusting a helper. Micro-packages of this size typically lean on str_*/preg_* without grapheme-cluster or i18n handling. If you need correctness guarantees around Unicode or localization, use symfony/string (already in the Laravel stack) or core Str instead.
  • No config, no extension points, no facade. There is nothing to publish or tune. The class is the entire surface; if a helper is nearly right, copy it into your own macro file and adapt — don't expect a config toggle.
  • Watch the package/repository name mismatch (revolution/laravel-str-mixins vs invokable/laravel-str-mixins). Minor, but it's friction for auditability and SBOM clarity when someone later asks "where does this come from?"
  • Removal is a one-line Composer change plus inlining still-used helpers into your internal class. Never make the package a refactor target for existing working code — adopt additively at new or touched call sites only.
  • Debugging tip: if a helper "doesn't exist," check provider registration first (php artisan about lists discovered providers), then Str::hasMacro() in Tinker. If it exists but returns the wrong result, suspect a collision — dump the closure with (new ReflectionMethod(Str::class, 'methodName'))->getClosure() and compare against the vendor source.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums