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 Ui Laravel Package

lorisleiva/artisan-ui

Artisan UI provides a clean web interface for browsing and running Laravel Artisan commands without leaving the browser. Inspect available commands, execute them, and review output from a convenient dashboard.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and get a working dashboard in three commands:

composer require lorisleiva/artisan-ui
php artisan vendor:publish --tag=artisan-ui   # publishes config + assets
php artisan serve

The dashboard is served at /artisan-ui by default. On first load you will see the buttons you have registered as actions — nothing is exposed automatically. The config file (config/artisan-ui.php) is where you control the route path, middleware, and which action classes are loaded.

Where to look first, in order:

  1. config/artisan-ui.php — set the path and, importantly, the middleware. Add 'auth' (or an admin gate) before you do anything else.
  2. The action registry declared in that config (or in a service provider, depending on version). This is the list of buttons the UI renders.
  3. The package README's "Actions" section — action classes are the primary extension point, and everything you build will subclass or register one.

The fastest first use case is wrapping a safe, idempotent, developer-facing command you already run by hand — cache:clear, queue:restart, queue:retry all, or route:clear. That gives you a working button in a few lines and validates that your middleware and route prefix are correct before you start wiring up anything destructive.

// config/artisan-ui.php (shape varies slightly by version)
return [
    'path' => 'admin/artisan-ui',
    'middleware' => ['web', 'auth', 'can:manage-system'],
    'actions' => [
        \App\ArtisanUi\Actions\ClearCache::class,
    ],
];

Implementation Patterns

Action class per capability. Do not dump raw command strings into config. Create a small action class per button (ClearCache, RestartQueue, BackupDatabase) so authorization, labelling, and input handling live next to the command they run and are unit-testable. This also keeps the config file stable while your operational surface grows.

Authorization on the action, not just the route. The route middleware gates the dashboard as a whole; per-action authorize() (or a can check inside handle()) gates the destructive buttons. This lets support staff see read-only actions while only SREs see migrate:fresh.

Treat actions as parameterised forms. The real value over a terminal is that you can expose a narrow, validated input surface: a list of queues, a date range, a tenant ID. Validate inputs, whitelist permitted values, and pass them as arguments/options to Artisan::call() rather than interpolating into a shell string.

public function handle()
{
    $this->validate(['queue' => 'required|in:default,emails,exports']);

    Artisan::call('queue:restart'); // or a parameterised command
    return 'Queue restarted.';
}

Group by operational domain, not by artisan namespace. Buttons grouped as Caches, Queues, Data, Deploy map onto how on-call engineers actually think. The package renders them flatly unless you organise the registry, so enforce grouping in your naming/config ordering.

Pair with logging and notifications. Have each action dispatch a log entry (Log::info('artisan-ui: restart queue by ' . auth()->id())) and, for anything long-running, a Slack notification on completion. The UI is an audit surface; treat every button press as an operational event.

Integration tip — deploy hook. The safest pattern is to register actions that mirror your deployment runbook (config:cache, route:cache, horizon:terminate) so post-deploy recovery is one click, but keep migrate and anything destructive behind a confirmation input or a separate gated action.

Use it as an internal ops console, not an admin panel. It complements Tinker, Horizon, and your APM tool; it does not replace them.

Gotchas and Tips

  • Maintenance status is the elephant in the room. Last release was June 2021 (Laravel 8 era), score 2.34. Expect to patch service-provider bindings or dependency constraints on Laravel 10/11. Budget an hour for compatibility testing before committing to it; pin a fork if you need it long-term.
  • Never expose the route without auth. The default middleware is minimal. A publicly reachable /artisan-ui is remote command execution as a service. Add auth plus a gate, and consider an IP allowlist middleware for production.
  • Run the package's config cache check early. If actions are registered in a service provider, php artisan config:cache in a deploy can produce an empty or stale action list if registration depends on config values. Test with config cached before shipping.
  • Long-running commands and the request lifecycle. Streaming output is nice but PHP max execution time and any upstream proxy timeout will cut it off. For migrations, backups, or bulk jobs, queue the command (Bus::dispatch(new RunCommand)) and let the action return "started", rather than blocking the UI.
  • Argument injection. Prefer Artisan::call('cmd', ['--option' => $validated]) over exec('php artisan cmd ' . $input). If the package's action wrapper shells out, audit every interpolation point.
  • Environment guard. Disable actions you do not want on production (e.g. migrate:fresh) using app()->isProduction() inside authorize() rather than trusting operators to click carefully.
  • Debugging a button that does nothing. Order of checks: route middleware (403), action authorize() (hidden vs. 403), config cache (empty registry), then the command itself (check storage/logs and Artisan::output()). Return output from handle() so failures are visible in the UI instead of silently swallowed.
  • Extension points to lean on: custom action classes (main one), published views (re-skin/brand), and the config's path/middleware (multi-tenant or environment-scoped mounting). Avoid forking the package internals; the shallow extension surface is a feature given its age.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console