mtownsend/laravel-make-trait
Adds a make:trait Artisan command to Laravel, letting you scaffold PHP traits from the CLI just like make:model or make:controller. Generates a clean trait stub in the right namespace automatically, saving boilerplate and keeping reusable trait files consistent across your project.
This package exists to fill one small gap in Laravel's scaffolding: there is no native make:trait command. Installing it gives you php artisan make:trait Name, which drops a trait stub into your app's traits directory with the correct namespace and name.
Minimal steps:
composer require --dev mtownsend/laravel-make-trait
composer.json/README against your Laravel version before relying on it — the last tagged release is from February 2023, so verify it works on the framework version you're actually running (Laravel 10/11/12 behavior around command registration has shifted over time).php artisan make:trait HasUuid
php artisan vendor:publish --provider="Mtownsend\MakeTrait\MakeTraitServiceProvider"
Where to look first: the generated file's namespace and location. That single detail determines whether the command is useful to you or just a faster mkdir.
First use case: generating a model concern — a HasUuid, Sluggable, or HasStatus trait — so you can drop it in app/Models/Concerns/ (or wherever your conventions put it) and use it in a model without hand-writing the boilerplate namespace + trait X { lines.
Model concerns as the primary workflow. The highest-value use is behavior that repeats across models — UUID primary keys, slug generation, soft-delete-like flags, audit fields. Generate once, then use HasUuid; in the models that need it. The command is trivial; the pattern of extracting shared model behavior into traits is what makes it worth having in your toolkit.
Config-driven paths. If the package supports a config file (check after publishing), point the trait path at your own convention — app/Models/Concerns, app/Support/Traits, app/Concerns, whatever your team standardizes on. Defaulting to app/Traits and then manually moving files defeats the purpose; make the config match your structure so the generated namespace is immediately correct.
Pairing with your own stubs. If the published config exposes stub customization, keep a project stub that includes your house style — declare(strict_types=1), a docblock, a @mixin hint, or a pre-filled boot method for traits that need static boot hooks on models. This turns a generic generator into a project-conventions generator.
Service-layer and support traits. Traits aren't only for Eloquent. If you have repetitive behavior in services or value objects (a FormatsDates trait, a HasRetry trait), the command is equally usable there. Adjust the config path or namespace mapping so service traits don't end up mixed with model concerns.
Scripting and scaffolding pipelines. Because it's a simple Artisan command, it composes with shell scripts and IDE Live Templates. If you generate multiple related classes at once (a model, a policy, a trait concern), wrapping the invocations in a project shell script is straightforward.
IDE alternative. If you use PhpStorm, a live template for trait is arguably a better fit than a package — no dependency, works offline, works in any project. The package is only clearly better when the team wants a consistent CLI-based workflow (onboarding scripts, CI scaffolding, containerized make: commands), not when an individual wants faster typing.
Maintenance risk is the headline concern. Fourteen stars, zero known dependents, and a single release in early 2023 means this is effectively unmaintained. That's fine for a scaffolding command that does almost nothing — it can't really "break" semantically — but it can break at the integration layer if Laravel changes how commands register or how stubs are discovered. Treat it as a convenience, not a dependency: if it stops working, you can inline the ~30 lines of command logic into your own app/Console/Commands in an afternoon.
Don't ship it in production. composer require --dev keeps it out of runtime installs. There's no reason for an Artisan generator to be present in production containers.
Verify the namespace against your PSR-4 autoloading. If you run composer dump-autoload and the trait file isn't picked up, the most likely cause is a path/namespace mismatch between the generated file and your composer.json PSR-4 map. Don't debug the package first; debug your autoloader.
Watch for stub overwrites. Many generators happily overwrite an existing file. Before regenerating a trait you've already edited, check whether the command prompts for confirmation or silently replaces. If silent, prefer creating a differently named trait rather than rerunning the command.
Config caching bites. If you publish and then edit the config, remember php artisan config:cache — a stale cache is the usual reason a path/namespace change appears to have no effect, especially in Docker setups where the cache is built during image creation.
Escape hatch is cheap. The entire functionality is a subclass of Laravel's Command with a stub. If the package causes any friction — version constraint conflicts, autodiscovery issues, abandoned notice in composer outdated — copy the pattern into a local command and uninstall. For a single missing make: verb, the tradeoff is almost always in favor of owning the small amount of code.
Check what it actually adds. Before committing to it in a team workflow, diff its artisan list contribution against your framework version. Newer Laravel releases have expanded scaffolding (including more -- flags and stub publishing on native generators), and you may find the gap it fills is smaller than it was in 2023 — in which case a snippet or IDE template is the more durable choice.
How can I help you explore Laravel packages today?