toufiqakki / laravel-artisan-route-explorer
Instant, interactive Laravel route search with fuzzy matching and route inspection.
Package info
github.com/ToufiqAkki/laravel-artisan-route-explorer
pkg:composer/toufiqakki/laravel-artisan-route-explorer
Requires
- php: ^8.2
- ext-mbstring: *
- illuminate/console: ^12.0 || ^13.0
- illuminate/routing: ^12.0 || ^13.0
- illuminate/support: ^12.0 || ^13.0
- laravel/prompts: ^0.3.24
- symfony/console: ^7.2 || ^8.0
Requires (Dev)
- laravel/pint: ^1.27
- orchestra/testbench: ^10.0 || ^11.0
- phpunit/phpunit: ^11.5.50 || ^12.5.8
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Find the route you need without repeatedly running route:list. Open the explorer, type part of a URI, name, controller, method, middleware, or domain, and watch the matching routes update immediately. Press Enter to inspect a route, then Escape to continue searching.
An additional Artisan developer tool. Laravel's built-in route:list remains available and unchanged.
Installation
The Composer package is toufiqakki/laravel-artisan-route-explorer. Once published:
composer require toufiqakki/laravel-artisan-route-explorer --dev
Laravel discovers the service provider automatically. No configuration, migrations, or publishing commands are needed.
To install this source before publication, add a Composer path repository in a Laravel application, replacing the path with your local package checkout:
composer config repositories.route-explorer path /absolute/path/to/laravel-route-explorer composer require toufiqakki/laravel-artisan-route-explorer:@dev --dev
Usage
php artisan route:search # Alias: php artisan route:explore # Start with a query: php artisan route:search users
All routes appear immediately. Type to search without pressing Enter. Matching letters appear in yellow, including fuzzy matches. A blue background and › mark the selected row. A context line explains matches in fields hidden from the table, such as middleware or domain.
Enter opens a scrollable details view with full methods, URI, name, action, controller, declared middleware, resolved middleware, domain, and parameter names. Escape returns to the same search and selection. Closing the explorer restores your previous terminal screen.
Features
- Instant, case-insensitive search across URI, route name, HTTP methods, controller/action, middleware, and domain.
- Predictable ranking: exact field matches, prefixes, substrings, then ordered fuzzy subsequences.
- Matched-letter highlighting, including in long, truncated fields.
- Keyboard navigation, paging, and route inspection within one session.
- Controller middleware and middleware groups, with Laravel's middleware exclusions respected.
- Web, API, closure, resource, invokable, domain, unnamed, and multi-method routes.
- Responsive columns and scrolling for large route collections.
- In-memory searching: routes are collected and normalized once per command.
- Plain table and JSON output for scripts and terminals without interactive support.
Matching and ranking
For example, usrctrl matches UserController, and auth can match a route name, action, declared alias such as auth:sanctum, or a resolved middleware class. Exact matches against individual HTTP methods and middleware also receive first priority.
Fuzzy matching starts at three characters. Characters must appear in order within one field. Ties prefer fewer skipped characters, then an earlier match, then the original route registration order. Duplicate-looking routes are retained. Search text is a single phrase; spaces do not introduce an expression language. Interactive queries are limited to 256 characters.
Use --no-fuzzy for strict substring searching:
php artisan route:search users --no-fuzzy
Filters
Filters reduce the dataset before opening the browser and remain active when Escape clears the query. Filters combine with AND. Repeated methods combine with OR, matching complete HTTP methods; all other filters use case-insensitive substrings.
php artisan route:search --method=POST php artisan route:search --method=PUT --method=PATCH php artisan route:search --middleware=auth --path=api php artisan route:search --name=users --domain=api.example.com
Noninteractive use
php artisan route:search users --plain php artisan route:search --method=GET --json php artisan route:search auth --no-interaction
Piped output, --no-interaction, --no-ansi, native Windows, and TERM=dumb automatically use a plain table. Quiet/silent mode exits without opening a hidden interactive session. --json outputs an array of route objects and takes precedence over --plain. No matches produce [] and a successful exit status. Neither mode reads keyboard input. Set NO_COLOR to disable highlighting while retaining the interactive browser.
Keyboard Shortcuts
| Key | Route list | Details |
|---|---|---|
| Typing | Update search immediately | Ignored |
| Backspace | Remove the last character | Ignored |
| ↑ / ↓ | Previous / next result | Scroll |
| Ctrl+P / Ctrl+N | Previous / next result | Scroll |
| Page Up / Page Down | Move one page | Scroll one page |
| Home / End | First / last result | Top / bottom |
| Enter | Inspect selected route | Stay in details |
| Esc | Clear the search | Return to the list |
| Ctrl+C / Ctrl+D | Exit | Exit |
j and k are search characters. Query editing appends at the end; left/right cursor editing is not currently implemented. Keyboard shortcuts are displayed in both views.
Screenshots / Demo
Laravel Route Explorer
Search: users_
───────────────────────────────────────────────────────────────────
Methods URI Name Action
› GET|HEAD users users.index UserController…
POST users users.store UserController…
GET|HEAD users/{user} users.show UserController…
3/120 routes · Selected 1/3
↑↓ Move · Enter Details · Esc Clear
PgUp/PgDn · Home/End · Ctrl+C Exit
Requirements
| Laravel | PHP |
|---|---|
| 12.x | 8.2–8.5 |
| 13.x | 8.3–8.5 |
- Composer 2 and
ext-mbstring. - Laravel Prompts 0.3.24 or later in the 0.3 series, installed automatically by Composer.
- For interactive mode: Linux, macOS, or Windows through WSL; a UTF-8 ANSI terminal;
sttyand PHP process functions enabled. - A terminal of at least 36 columns × 11 rows. Below that size a resize hint is shown. Roughly 100 columns shows all primary table columns; details remain available in narrower windows.
The route snapshot reflects the booted application, including vendor routes and cached routes. Routes are never executed. Gathering legacy controller middleware may construct controllers through Laravel's container, as Laravel's own route inspection does. If controller middleware cannot be collected, the route remains available with a metadata warning. Global HTTP middleware, source file locations, and parameter binding implementations are not included. Group aliases are retained alongside a separate resolved middleware list.
Architecture
Laravel Router → RouteCollector → immutable RouteEntry[]
↓
RouteFilter
↓
RouteSearcher + RouteMatcher
↓
ranked SearchResult[] + highlights
↓
ExplorerState → RouteListView / RouteDetailView
↓
Laravel Prompts adapter
The command coordinates discovery, filtering, output mode, and the interactive session. Searching is independent of Laravel's output and terminal rendering. Normalized fields are indexed once. Search results contain character positions so the view does not implement matching a second time. RouteMatcher can be replaced using a container binding.
The UI extends Laravel Prompts for TTY setup, input, and cursor restoration. A small adapter splits buffered input, polls for resizing, and repaints an alternate screen. It avoids the inline prompt renderer's clipping when terminals shrink. No additional runtime TUI library is required. Sorting, export formats, or alternative UIs can be added without replacing route discovery.
Testing
From this package's directory:
composer install
composer test
composer format
composer benchmark
PHPUnit and Orchestra Testbench test discovery, normalization, middleware, search ranking, highlighting, 5,000-route datasets, keyboard state, terminal sizing, JSON output, and command registration. The included GitHub Actions workflow targets Laravel 12 and 13 across their PHP versions when this package is the repository root.
On Linux or macOS, also run the real terminal integration test (Python 3 standard library only):
python3 tests/terminal_smoke.py
It checks live input without Enter, ANSI highlighting, paging, details, literal console markup, pasted input, idle resizing, empty results, Ctrl+C, and restoration of the terminal mode, cursor, and prior screen. The benchmark reports timings rather than asserting a hardware-dependent latency threshold.
Contributing
Open an issue describing the use case or bug. For a change, keep discovery, matching, and rendering separate; add focused regression tests; run the tests and formatter; and describe the behavior and validation in your pull request. Keep new runtime dependencies small and justify them.
Before the first public release, choose an available Composer vendor namespace, update the installation examples, publish this package directory as the repository root, and tag the release. Do not publish the surrounding development application. Packagist installation becomes available after registering that repository.
License
MIT.