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

Artisan Standalone Laravel Package

matthewbdaly/artisan-standalone

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package in a non-Laravel PHP project:

composer require matthewbdaly/artisan-standalone

First look at the package README and vendor/matthewbdaly/artisan-standalone/src/. The main integration point is the package’s standalone Application class. Create an executable artisan or bin/console bootstrap that loads Composer and registers your commands:

#!/usr/bin/env php
<?php

require __DIR__ . '/vendor/autoload.php';

use Matthewbdaly\ArtisanStandalone\Application;

$app = new Application;
$app->add(new App\Console\Commands\SyncCommand);
$app->run();

Then write commands using Laravel’s existing console API:

namespace App\Console\Commands;

use Illuminate\Console\Command;

class SyncCommand extends Command
{
    protected $signature = 'sync:users {--dry-run}';
    protected $description = 'Sync users from an external source';

    public function handle(): int
    {
        if ($this->option('dry-run')) {
            $this->info('Dry run only');
            return self::SUCCESS;
        }

        // Do work here

        $this->info('Sync complete');
        return self::SUCCESS;
    }
}

Your first practical use case is usually a small internal CLI for a package or plain PHP app: data imports, cleanup jobs, cache warmers, or maintenance scripts that you want to run with the familiar Artisan signature, info(), table(), ask(), and confirm() APIs without installing Laravel.

Implementation Patterns

Use one bootstrap file per project and keep command registration explicit. A small bin/console is easier to test and debug than scattering registration logic across many files:

$app = new Matthewbdaly\ArtisanStandalone\Application;
$app->add(new App\Console\Commands\ImportUsers);
$app->add(new App\Console\Commands\PruneRecords);
$app->run();

Treat the standalone application as a thin console layer, not as a Laravel application. Put business logic in plain services and inject them into commands via constructors or manually pass them in. Commands should be adapters: parse options, call a service, format output, and return an exit code.

For project-level workflows, add the bootstrap to Composer’s bin section so it is available as vendor/bin/console after install:

{
  "bin": ["bin/console"]
}

This is useful when the package is installed as a dependency and consumers need to run your commands.

For maintenance scripts, wrap common operations in commands rather than ad hoc PHP scripts. For example:

class CleanupCommand extends Command
{
    protected $signature = 'cleanup {--days=30}';
    protected $description = 'Delete stale records';

    public function handle(RecordCleaner $cleaner): int
    {
        $deleted = $cleaner->olderThan((int) $this->option('days'));
        $this->info("Deleted {$deleted} records");
        return self::SUCCESS;
    }
}

If you need interactive commands, use Artisan’s built-in helpers ($this->ask(), $this->confirm(), $this->choice()) rather than raw readline() calls. They behave consistently and are easier to test.

For testing, instantiate the command directly and execute it with Symfony’s CommandTester:

use Symfony\Component\Console\Tester\CommandTester;

$tester = new CommandTester(new SyncCommand);
$tester->execute(['--dry-run' => true]);

$this->assertSame(0, $tester->getStatusCode());
$this->assertStringContainsString('Dry run only', $tester->getDisplay());

For cron and CI jobs, invoke the bootstrap with an absolute path and set the working directory explicitly:

cd /var/www/app && /usr/bin/php bin/console sync:users

Gotchas and Tips

This is not a full Laravel application. You do not get app(), facades, service providers, auto-discovery, config loading, .env parsing, queues, scheduling, or the HTTP kernel unless you wire those pieces yourself. Assume you must pass dependencies and configuration explicitly.

Command registration is manual. If a command does not appear in php bin/console list, confirm that it is added before $app->run(), that the class is autoloadable, and that its $signature is valid. If you override the command constructor, call the parent constructor so Artisan can configure the definition.

Version compatibility is the main risk. This is a small, older package, so check its Composer constraints against your PHP and illuminate/console versions. Pin compatible versions rather than assuming it works with the latest Laravel components.

Avoid relying on Laravel helper functions and facades inside commands. If a command needs configuration, pass it into the constructor or load it in the bootstrap. If you need environment variables, read them explicitly with getenv() or a config library.

Return integer exit codes from handle() and avoid exit() or die() inside commands. That keeps commands testable and lets the console application report failures correctly. Use $this->error() for failures and let exceptions bubble up unless you want to render a friendly message yourself.

Debug with the usual Symfony/Artisan tools: php bin/console list, php bin/console help your:command, and -vvv for verbosity. If you hit container or dispatcher errors, inspect the package’s Application bootstrap first; it is the piece responsible for adapting Illuminate’s console component to a standalone context.

Use the package as an extension point. If you need shared bootstrapping, custom global options, or a common base command, wrap the package’s Application in your own console class or create a shared bin/console script. Keep destructive commands guarded with confirm() or --force, since there is no Laravel authorization layer in a standalone CLI.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings