laravel/prompts
Laravel Prompts adds beautiful, user-friendly interactive forms to PHP CLI apps and Artisan commands. It supports placeholder text, validation, and a browser-like input experience, making it easy to collect and validate user input in the terminal.
Installation:
composer require laravel/prompts
No additional configuration is required—just use the package in your Artisan commands or CLI scripts.
First Use Case:
Replace basic Symfony\Component\Console\Question\Question with Prompt\Prompt for richer input handling.
use Laravel\Prompts\Prompt;
$name = Prompt::text('What is your name?');
echo "Hello, $name!";
Where to Look First:
Prompt::* static methods (e.g., Prompt::select(), Prompt::confirm()).Interactive Forms:
Use Prompt::form() to group related inputs into a multi-step UI:
$result = Prompt::form([
'name' => Prompt::text('Name'),
'age' => Prompt::number('Age', min: 18),
'admin' => Prompt::confirm('Admin?', default: false),
]);
Conditional Logic: Dynamically show/hide steps based on previous answers:
$form = Prompt::form([
'role' => Prompt::select('Role', ['dev', 'designer']),
'framework' => Prompt::select('Framework')->when('role', 'dev'),
]);
Data Validation: Validate inputs inline with Laravel-style rules:
$email = Prompt::text('Email', validator: fn ($email) =>
Validator::make(['email' => $email], ['email' => 'required|email'])
);
Progress Tracking:
Use Prompt::progress() for long-running tasks:
Prompt::progress()->spin('Processing...', fn () => sleep(3));
Artisan Commands:
Replace $this->ask() with Prompt::text() for consistency and richer UX.
protected $signature = 'user:create';
public function handle(): void
{
$name = Prompt::text('Name');
// ...
}
Non-Interactive Mode:
Disable prompts in CI/CD with Prompt::nonInteractive():
if (Prompt::nonInteractive()) {
$name = 'default-name';
} else {
$name = Prompt::text('Name');
}
Custom Helpers:
Extend with reusable components (e.g., Prompt::helper('table', fn () => ...)).
Default Values:
0, false) may not work as expected in select prompts. Use null or explicit strings.Prompt::select('Option', ['a', 'b'], default: 'a').Validation Quirks:
fn ($val) => $val > 0) may fail silently. Use closures:
validator: fn ($val) => $val > 0 ? true : 'Must be > 0'
Multibyte Characters:
Windows Line Endings:
Prompt::clear() to reset the terminal if needed.Silent Failures:
Wrap prompts in try-catch to handle terminal read errors gracefully:
try {
$input = Prompt::text('Input');
} catch (\Throwable $e) {
$input = 'fallback';
}
Non-Interactive Mode:
Ensure your app checks Prompt::nonInteractive() early to avoid hangs in CI.
Custom Prompt Types:
Extend Laravel\Prompts\Prompt to add domain-specific inputs (e.g., Prompt::color()).
Styling:
Override default styles via Prompt::style() or Symfony’s NamedStyle:
Prompt::style('error', fn () => '<fg=red>Error</>');
Testing:
Mock prompts in tests using Prompt::fake():
Prompt::fake(['name' => 'test']);
$name = Prompt::text('Name'); // Returns 'test'
Dynamic Options:
Use Prompt::select() with a closure for runtime-generated options:
Prompt::select('User', fn () => User::all()->pluck('name', 'id'))
Multi-Select Shortcuts:
Allow "Select All" with Prompt::multiselect(..., allowSelectAll: true).
Progress Bars:
Update dynamically with Prompt::progress()->spin('Task', fn () => $this->process()).
```markdown
### Config Quirks
- **No Config File**: Laravel Prompts is zero-config. All behavior is controlled via method arguments.
- **Global Defaults**: Set defaults in a service provider if reused across commands:
```php
Prompt::macro('custom', fn ($question, $default = null) =>
Prompt::text($question, default: $default, validator: fn ($val) => $val !== 'invalid')
);
How can I help you explore Laravel packages today?