joshembling/artisan-browse
Browse, search, and run your Laravel Artisan commands interactively—no more memorizing command names. Explore every command registered in your app, read descriptions and signatures, then execute directly. A fast, keyboard-friendly way to discover what Artisan can do and get things done.
Install as a dev dependency. This is a developer-experience tool; it has no business in production vendor/:
composer require --dev joshembling/artisan-browse
Laravel's package auto-discovery registers the service provider, so no manual provider entry is needed. If discovery is disabled in your project, run php artisan package:discover after install.
First use case. Open a terminal in the project root and launch the UI:
php artisan browse
You get a searchable list of every command registered in the application — framework commands, your app/Console/Commands classes, and commands contributed by other packages. Type to fuzzy-filter, arrow keys to move, Enter to run.
Where to look first when you have questions:
config/artisan-browse.php (publish with php artisan vendor:publish --tag=artisan-browse-config if it exists) — this is where exclusions, keybindings, and display options live.php artisan list, that's a registration/discovery problem, not a browse problem.vendor/joshembling/artisan-browse/src — the package is small; the command registry and the UI component are the two files worth reading.Verify your terminal first. The TUI relies on interactive terminal capabilities (cursor control, raw input). Confirm that php artisan browse renders correctly in your actual shell — iTerm2, Windows Terminal, GNOME Terminal — before recommending it to the team. If it renders as a wall of escape codes, your terminal or TERM variable is the issue, not Laravel.
Onboarding and codebase discovery. The highest-value use is for developers new to a large or inherited codebase. Instead of php artisan list | grep, they search by intent ("migrate", "queue", "seed") and see the full signature including options. Put php artisan browse in your README under "Local development" and in your onboarding doc — it replaces a paragraph of explanation about which commands exist.
Signature inspection before execution. Use the browser as a live reference for a command's arguments and options. This is faster than php artisan help <command> when you don't yet know the command name. Pattern: search a keyword → arrow to the candidate → read the signature → run, or back out and use the CLI directly if you need to script it.
Composer script shortcut. For teams that use this daily, expose it:
{
"scripts": {
"browse": "php artisan browse"
}
}
Now composer browse works from any subdirectory of the project and matches muscle memory for people already running composer test.
Complement, don't replace, artisan list. The TUI is for humans at a keyboard. Keep php artisan list (and artisan list --format=json) in CI scripts, documentation generators, and shell completions. The mental model: TUI for exploration, list/help for automation.
Pair with Laravel Prompts-aware commands. Commands that are themselves interactive (they call $this->ask() or use Prompts) will take over the terminal once launched. Flow: browse to find the command, then decide — if it's interactive, running it from inside browse works fine; if it's long-running (queue worker, serve, horizon), exit the browser first and run it in its own pane so you keep terminal control.
Team-specific command namespaces. If your app registers domain commands (php artisan billing:reconcile, php artisan reports:rebuild), the browser becomes a discoverable index of internal tooling. Encourage consistent namespace:action naming — fuzzy search quality depends heavily on it.
It needs a real TTY. This is the number-one source of confusion. php artisan browse will not work:
docker exec without -it,exec(), Process::run(), or a queue job,php artisan browse | cat).Symptom is usually a hang, an immediate exit, or garbage output. Guard any wrapper script with if (stream_isatty(STDIN)) or simply never call it from automation.
--dev is not optional. Because the package is a dev dependency, a composer install --no-dev in production will remove it. Don't reference php artisan browse from any runtime code path, health check, or deployment script.
Config and route caching. If the UI appears to ignore your published config, you almost certainly have a cached config: run php artisan config:clear. Same class of bug as any Laravel package.
Package discovery after adding commands dynamically. If you register commands at runtime (e.g., conditionally in a service provider based on an env flag), the browse list reflects whatever is registered in that boot. If a command is missing, check the condition guarding its registration before blaming the browser.
Commands with side effects run immediately on Enter. There is no dry-run mode. Treat Enter as "execute." For destructive commands, prefer typing them out manually or wrapping them in a confirmation prompt in your own command class — the TUI's selection step is not a confirmation step.
Wide signatures and narrow terminals. Long command descriptions and options wrap or truncate depending on terminal width. If output looks clipped, widen the window or reduce font size; don't file it as a bug.
Windows and WSL. Native cmd.exe and older PowerShell versions have weaker ANSI support. Windows Terminal and WSL2 are fine. If a teammate reports broken rendering, that's the first thing to check.
Long-running commands block the UI. Running queue:work or serve from inside the browser occupies the process. Ctrl-C typically returns you, but state can be inconsistent — prefer running daemons in a dedicated shell.
Extension points to reach for. Before forking or writing a wrapper, check the config for:
These are cheaper than maintaining a patch against a 90-star package.
Debugging rendering issues. Run with -vvv to surface exceptions from the UI layer, and test the same command directly (php artisan <cmd>) to isolate whether the problem is the browser or the underlying command. If php artisan list is fine but browse is broken, the issue is terminal-side; if both are broken, it's registration-side.
How can I help you explore Laravel packages today?