orchestra/workbench
Orchestra Workbench helps you preview and interact with your Laravel package during development. Spin up a local app environment to test routes, views, migrations, and configuration while building and validating your package before release.
Install via Composer in your Laravel package project:
composer require --dev orchestra/workbench
Publish assets and config:
php artisan workbench:install
This generates stubs for:
app/Models/User.php (customizable via TESTBENCH_USER_MODEL)database/factories/UserFactory.phproutes/web.php (with /workbench routes)routes/console.php (for package commands)DatabaseSeeder.phpServe the Workbench:
php artisan workbench:serve
Access at http://localhost:8000/workbench (default port: 8000).
First Use Case:
php artisan workbench:test --command=your-package:command
/workbench and triggering endpoints.config/workbench.php (customize user model, ports, or default routes).workbench:serve – Launch the Workbench server.workbench:test – Run package-specific tests in isolation.workbench:devtool – Generate or update stub files.stubs/ – Predefined templates for models, factories, and routes.tests/ – Example test structure for package validation.For a Laravel package with a CLI command (php artisan your-package:command), use Workbench to:
php artisan workbench:test --command=your-package:command --args="test-arg"
/workbench and use the Artisan Runner to execute commands with real-time output.config/workbench.php:
'bindings' => [
YourPackageService::class => MockService::class,
],
graph TD
A[Code Package Feature] --> B[Run `workbench:devtool`]
B --> C[Update Stubs]
C --> D[Run `workbench:serve`]
D --> E[Test in Browser/CLI]
E --> F[Debug via Workbench Tools]
F --> A
use Orchestra\Workbench\Tests\TestCase;
class YourPackageTest extends TestCase {
public function test_command_output() {
$this->artisan('your-package:command')
->expectsOutput('Expected output')
->assertExitCode(0);
}
}
public function test_api_endpoint() {
$response = $this->get('/workbench/api/your-package');
$response->assertStatus(200);
}
Extend or replace stubs via workbench:devtool:
# Generate a custom stub (e.g., for a new model)
php artisan workbench:devtool --stub=model --name=YourModel --force
# Replace a stub file (e.g., routes)
php artisan workbench:devtool --replace=routes/web.php --path=custom/web.php
config/workbench.php:
'bindings' => [
\YourPackage\Services\PaymentGateway::class => \Mockery\MockInterface::class,
],
workbench:test to validate CLI commands:
php artisan workbench:test --command=your-package:command --args="--option=value"
Add to .github/workflows/test.yml:
jobs:
test-package:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
- run: composer install
- run: php artisan workbench:test --command=your-package:command --env=testing
// .vscode/tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "Workbench: Serve",
"type": "shell",
"command": "php artisan workbench:serve",
"problemMatcher": []
}
]
}
php artisan workbench:serve to a run configuration for quick access.Use WriteEnvironmentVariables action to inject config:
use Orchestra\Workbench\Actions\WriteEnvironmentVariables;
$action = new WriteEnvironmentVariables([
'APP_ENV' => 'testing',
'YOUR_PACKAGE_DEBUG' => 'true',
]);
$action->execute();
Extend Workbench’s actions (e.g., for database seeding):
use Orchestra\Workbench\Actions\Action;
class SeedDatabase implements Action {
public function execute() {
Artisan::call('db:seed', ['--class' => 'YourPackageSeeder']);
}
}
Register in config/workbench.php:
'actions' => [
\App\Actions\SeedDatabase::class,
],
For packages with shared dependencies, use Workbench’s namespace isolation:
# Test PackageA with PackageB mocked
php artisan workbench:test --package=PackageA --mock=PackageB
User Model Hardcoding:
Workbench\App\Models\User. If your package uses a custom user model, set TESTBENCH_USER_MODEL in .env:
TESTBENCH_USER_MODEL=App\Models\CustomUser
config/workbench.php:
'user_model' => \App\Models\CustomUser::class,
Route Conflicts:
/workbench routes, which may conflict with your package’s routes.config/workbench.php:
'routes' => [
'exclude' => ['/workbench/api/your-package'],
],
Stub Overwrites:
workbench:devtool without --force may fail if stubs exist.--force or customize stubs via --path:
php artisan workbench:devtool --stub=model --name=YourModel --path=custom/YourModel.php
PHP Version Mismatches:
composer.json:
"orchestra/workbench": "^10.0"
Database Seeding:
DatabaseSeeder may not match your package’s migrations.php artisan workbench:devtool --replace=database/seeders/DatabaseSeeder.php --path=custom/DatabaseSeeder.php
Check Workbench Logs:
tail -f storage/logs/laravel.log | grep -i workbench
Enable Debug Mode:
WORKBENCH_DEBUG=true
Inspect Stub Files:
Workbench stubs are stored in stubs/. Override them by copying to config/workbench/stubs/.
Clear Workbench Cache:
php artisan workbench:clear-cache
Test Artisan Commands:
Use the Artisan Runner in /workbench to debug commands interactively.
Port Binding:
8000. Change in .env:
WORKBENCH_PORT=9000
Asset Compilation:
npm
How can I help you explore Laravel packages today?