rap2hpoutre/create-user-command
A Laravel artisan command for creating users straight from the console. It prompts for details like name, email, and password, validates them, and saves the new record through your user model, making it handy for quick admin setup, local testing, or seeded accounts.
Install and confirm the command registers. Pull it in with Composer:
composer require rap2hpoutre/create-user-command
This package predates Laravel's package auto-discovery era, so after install check config/app.php for the service provider. If you don't see Rap2hpoutre\CreateUserCommand\CreateUserCommandServiceProvider::class (or similarly named) in providers, add it manually — otherwise php artisan make:user won't exist and you'll assume the package is broken when it's just unregistered.
Verify the command is available, then run it.
php artisan list | grep make:user
php artisan make:user
You'll get an interactive prompt for name, email, and password. The command validates input, hashes the password via Laravel's hasher, and persists through your User Eloquent model.
First place to look: the package source under vendor/rap2hpoutre/create-user-command/src. Read the command class before you run it — the exact prompt labels, validation rules, and default model/fields matter for anything beyond a stock Laravel users table. Then run:
php artisan vendor:publish --provider="Rap2hpoutre\CreateUserCommand\CreateUserCommandServiceProvider"
to see what config or stub files it exposes. That published output is your real documentation.
First real use case: replacing php artisan tinker + hand-typing User::create([...]) when you need a seeded admin or a known login on a fresh local/staging environment. It's a convenience command, not a production provisioning system.
Config-driven model and fields. If your auth model isn't App\User/App\Models\User, or your columns aren't name/email/password, publish the config and point the command at your model class and field names. This is the primary adaptation path and avoids touching vendor code.
// config/create-user-command.php (shape depends on published file)
return [
'model' => App\Models\Account::class,
'fields' => [
'name' => 'full_name',
'email' => 'email_address',
'password' => 'password_hash',
],
];
Override the command for extra fields. The package explicitly supports publishing/overriding the command. When you need role, tenant_id, is_admin, or a username, copy the published command into app/Console/Commands/ and extend the prompt/validation flow. Register it in your Kernel (or let Laravel's command discovery pick it up on newer versions) and stop calling the vendor command.
// app/Console/Commands/MakeUser.php
protected $signature = 'make:user';
public function handle()
{
$name = $this->ask('Name');
$email = $this->ask('Email');
$password = $this->secret('Password');
$role = $this->choice('Role', ['admin', 'editor', 'viewer'], 0);
$this->validate(...);
// create via your model, assign role, etc.
}
Local/staging seeding workflows. Use it inside a docker-compose exec app php artisan make:user step, or as the documented "create your first admin" step in your README's setup instructions. It reads better than a raw tinker snippet and validates input for you.
Custom hashing / additional side effects. If creating a user should also, say, send a welcome mail or generate an API token, override the command and add those after the create() call. Don't try to jam side effects into the model's creating event — a CLI admin-creation command and normal registration likely want different behavior.
Testing integration. Because it's interactive, test the underlying creation logic via the model factory in feature tests rather than driving the command. If you must test the command, use $this->artisan('make:user')->expectsQuestion(...)->assertExitCode(0) with Laravel's built-in prompt expectations — this is the cleanest way to cover your overridden version.
Last release was 2016 — audit against your Laravel version. The command API is stable, so it often still runs on modern Laravel, but validate before relying on it: service provider registration style, config publishing tags, and password validation rules are all from the 5.x era. On Laravel 10/11/12 confirm the provider still boots and the published config is still loaded; if it fails, overriding the command and dropping the vendor dependency is usually cheaper than patching it.
Double hashing with the hashed cast. This is the biggest footgun. The package hashes the password itself. If your model casts 'password' => 'hashed' (or has a setPasswordAttribute mutator that hashes), you'll hash twice and logins will fail. Either remove the cast/mutator for this model or override the command to skip manual hashing.
Mass-assignment silently drops fields. The command persists via Eloquent, so every field it prompts for must be in $fillable (or you must have guarded open). A missing name in $fillable won't throw loudly in older Laravel — you may get a user with an empty name. Verify the created row after your first run.
Interactive-only: it blocks CI and non-TTY contexts. There are no --name/--email flags. Running it in a Docker build or CI pipeline without a TTY hangs or fails. For automated environments use a seeder, a small --no-interaction wrapper command you write, or php artisan tinker --execute. Treat this command as human-facing only.
"Skips existing emails" is silent. The duplicate-email guard means re-running the command with an existing address won't necessarily error — confirm what it prints. In scripts, never assume "ran without exception" means "user created"; check the exit output or query the DB.
Validation rules are opinionated and dated. Password length/complexity from a 2016 package may not meet your current policy (NIST-length guidance, etc.). Override the validate() rules in your published command rather than accepting the defaults, especially if password is collected without confirmation.
Field/table naming drift breaks it quietly. If you rename name → full_name but only update the config, verify the command actually uses it; a mismatch surfaces as a failed insert or a null column, not a friendly error. Test one run end-to-end after any schema change.
Publishing overwrites risk. Once you publish and customize the command, pin the package version in composer.json (or remove it entirely). An update that changes the vendor command's signature/stub can reintroduce drift between your override and upstream, and the command registration may collide (two make:user signatures).
Debugging tip. Add -v and inspect the command's $this->line()/error output; if prompts misbehave under a test harness, use expectsQuestion with the exact prompt text from the source, not your paraphrase. When in doubt, php artisan help make:user shows the registered signature and confirms which class is actually bound.
How can I help you explore Laravel packages today?