cleaniquecoders/traitify
Traitify is a Laravel package that helps keep Eloquent models lean by moving reusable logic into well-organized traits. It provides a simple workflow for creating, managing, and applying shared model behavior across your application, making code easier to maintain and reuse.
composer require cleaniquecoders/traitify:^1.4
illuminate/contracts 11.x, 12.x or 13.x. The 1.4.0 release is the first to allow ^13.0, so this is the version to pin if your app is tracking Laravel 13; on Laravel 11/12 there is nothing forcing you off 1.3.1.config/traitify.php (publish with php artisan vendor:publish --tag=traitify-config) and its src/Concerns directory — the traits shipped there are the reference for naming and boot{TraitName}() conventions the package expects.use statement on the model, and confirm behaviour is unchanged with your existing model test suite before deleting the original methods. This is the lowest-risk way to learn the package's conventions (naming, boot hooks, config keys) without touching framework-level integration.Trait-per-concern, one file each. Keep traits single-purpose (HasSlug, Publishable, Searchable) rather than one UserTrait grab-bag. Traitify's value compounds when traits are small enough to compose across models.
Use Eloquent boot hooks for registration. Anything that needs to run at model boot (event listeners, global scopes, cast registration) belongs in boot{TraitName}() / initialize{TraitName}() inside the trait, not in the model's booted(). This keeps the model clean and makes the trait portable to the next model — which is the entire point of extracting it.
Compose across models, not just within one. A HasUuid or Publishable trait applied to Post, Page and Product is a far better signal that the abstraction is right than a trait used exactly once. If a trait only ever has one consumer, it is a private method pretending to be reusable.
Pair with migrations/contracts. When a trait implies columns (published_at, slug), ship the corresponding migration stub or a HasPublishableColumns docblock alongside it so the trait is not silently broken by a schema change.
Test the trait in isolation with a fixture model. Create tests/Fixtures/Models/TestModel.php that uses only the trait under test, rather than asserting through User in every test. This survives refactors of your real models and is exactly what the package's own PHPUnit 12 / Pest 4 support is set up for — you can use #[Test] attributes or Pest's it() syntax freely.
CI matrix alignment. If you mirror the package's setup, note 1.4.0 targets a Laravel 12 matrix with Larastan ^3.0 and PHPStan plugins ^2.0. Mirroring those dev dependency ranges locally keeps static analysis output comparable to the package's own.
getSlug() on the same model is a fatal error, not a warning at autoload time. Resolve explicitly with insteadof/as in the model's use block, and keep an eye on the as aliases when you rename methods in a trait — aliases do not follow renames.protected static array $cache inside a trait used by three models gives three independent caches, which is usually what you want but occasionally is not. Prefer instance state or an injected service for anything shared.boot{TraitName}() only fires for Eloquent models. Controllers, form requests and jobs get no automatic boot hook — if you are relying on Traitify's initialisation convention outside a model, it will not run and you will debug it for an hour.phpunit.xml.dist to drop deprecated PHPUnit 10 attributes, but the equivalent trap on your side is @dataProvider, @covers and @test annotations — these are gone in PHPUnit 12. Convert to #[DataProvider], #[CoversClass], #[Test]. Pest 4 handles this differently again, so don't copy assertions between the two test suites blindly.1.4.0 is additive, not breaking — but pin it deliberately. Nothing in the changelog removes API surface, so ^1.4 is safe for Laravel 11/12 consumers. The one thing to verify is that your own constraints on illuminate/contracts do not conflict with the widened ^13.0 range if you are still on 11.x — Composer will resolve it, but check composer why-not cleaniquecoders/traitify 1.4.0 if the update refuses to land.How can I help you explore Laravel packages today?