Laravel Artisan Commands Reference

A reference for Laravel's Artisan command-line tool: built-in commands and writing your own.

Useful built-in commands

CommandDoes
php artisan serveRuns the built-in dev server.
php artisan tinkerAn interactive REPL with the app already booted — great for poking at models/queries.
php artisan migrateRuns pending migrations. Add --force to run without confirmation in production.
php artisan migrate:rollbackReverts the last migration batch.
php artisan make:model Post -mfcGenerates a model plus, in one go, a migration (-m), factory (-f), and controller (-c).
php artisan route:listLists every registered route.
php artisan config:cacheCompiles all config files into one cached file for production performance.
php artisan config:clear / cache:clear / route:clear / view:clearClear the respective cache — reach for these first when changes don't seem to take effect.
php artisan queue:workProcesses queued jobs.
php artisan schedule:workRuns the task scheduler in the foreground, for local development.
php artisan aboutPrints a summary of the app's environment and configuration.

Writing a custom command

php artisan make:command SendWeeklyDigest
class SendWeeklyDigest extends Command
{
    protected $signature = 'digest:send {--dry-run}';

    protected $description = 'Email the weekly digest to subscribed users';

    public function handle(): int
    {
        $users = User::where('subscribed', true)->get();

        $this->info("Sending to {$users->count()} users...");

        if (! $this->option('dry-run')) {
            $users->each(fn ($user) => Mail::to($user)->send(new WeeklyDigest($user)));
        }

        return self::SUCCESS;
    }
}
php artisan digest:send
php artisan digest:send --dry-run

Signature syntax

SyntaxMeaning
{user}Required argument.
{user?}Optional argument.
{user=1}Optional argument with a default.
{--queue}Boolean flag/option, e.g. --queue.
{--queue=default}Option that takes a value, with a default.

User interaction and output

$this->info('All good.');
$this->warn('Careful.');
$this->error('Something failed.');

$name = $this->ask('What is your name?');
$confirmed = $this->confirm('Do you wish to continue?');
$choice = $this->choice('Pick an environment', ['local', 'staging', 'production']);

$this->table(['Name', 'Email'], $users->map->only(['name', 'email']));

$this->withProgressBar($users, function ($user) {
    // ...
});

Running a command from code

use Illuminate\Support\Facades\Artisan;

Artisan::call('digest:send', ['--dry-run' => true]);

// Also how the scheduler runs commands
Schedule::command('digest:send')->weekly();

Artisan::call() runs the command synchronously in the current process and returns its exit code, which is handy for triggering one command from inside another. For anything that should run independently of the request lifecycle — a nightly digest, a report — scheduling it via Schedule::command() is almost always the better fit than calling it manually.

Tinker

php artisan tinker drops into a REPL with the full application already booted, so Eloquent models, facades, and helper functions are all available immediately — no bootstrapping required. It's the fastest way to check a query, inspect a model's relationships, or try out a snippet before committing it to a controller:

>>> User::where('subscribed', true)->count()
>>> $user = User::find(1);
>>> $user->posts()->latest()->first()
>>> event(new OrderShipped($order)); // fire an event manually
>>> Mail::to($user)->send(new WeeklyDigest($user));

Because Tinker holds the app in memory across calls, changes made to model files while a session is open aren't picked up until it's restarted — a common source of confusion when a fix "doesn't seem to work" in Tinker after an edit.

Command dependencies and testing

Like controllers, a command's handle() method supports method injection — Laravel resolves type-hinted arguments out of the container automatically, on top of whatever the signature captured:

public function handle(MailerService $mailer): int
{
    $mailer->sendDigest();

    return self::SUCCESS;
}

Commands are also straightforward to test without actually running them from the terminal, using the same testing helpers as HTTP tests:

$this->artisan('digest:send', ['--dry-run' => true])
    ->expectsOutput('Sending to 12 users...')
    ->assertExitCode(0);