| name | laravel-prompts |
| description | Laravel Prompts - Beautiful and user-friendly forms for command-line applications with browser-like features including placeholder text and validation |
Laravel Prompts Skill
Laravel Prompts is a PHP package for adding beautiful and user-friendly forms to your command-line applications, with browser-like features including placeholder text and validation. It's pre-installed in Laravel and supports macOS, Linux, and Windows with WSL.
When to Use This Skill
This skill should be triggered when:
- Building Laravel Artisan commands with interactive prompts
- Creating user-friendly CLI applications in PHP
- Implementing form validation in command-line tools
- Adding text input, select menus, or confirmation dialogs to console commands
- Working with progress bars, loading spinners, or tables in CLI applications
- Testing Laravel console commands with prompts
- Converting simple console input to modern, validated, interactive prompts
Quick Reference
Basic Text Input
use function Laravel\Prompts\text;
// Simple text input
$name = text('What is your name?');
// With placeholder and validation
$name = text(
label: 'What is your name?',
placeholder: 'E.g. Taylor Otwell',
required: true,
validate: fn (string $value) => match (true) {
strlen($value) < 3 => 'The name must be at least 3 characters.',
strlen($value) > 255 => 'The name must not exceed 255 characters.',
default => null
}
);
Password Input
use function Laravel\Prompts\password;
$password = password(
label: 'What is your password?',
placeholder: 'password',
hint: 'Minimum 8 characters.',
required: true,
validate: fn (string $value) => match (true) {
strlen($value) < 8 => 'The password must be at least 8 characters.',
default => null
}
);
Select (Single Choice)
use function Laravel\Prompts\select;
// Simple select
$role = select(
label: 'What role should the user have?',
options: ['Member', 'Contributor', 'Owner']
);
// With associative array (returns key)
$role = select(
label: 'What role should the user have?',
options: [
'member' => 'Member',
'contributor' => 'Contributor',
'owner' => 'Owner',
],
default: 'owner'
);
// From database with custom scroll
$role = select(
label: 'Which category would you like to assign?',
options: Category::pluck('name', 'id'),
scroll: 10
);
Multiselect (Multiple Choices)
use function Laravel\Prompts\multiselect;
$permissions = multiselect(
label: 'What permissions should be assigned?',
options: ['Read', 'Create', 'Update', 'Delete'],
default: ['Read', 'Create'],
hint: 'Permissions may be updated at any time.'
);
// With validation
$permissions = multiselect(
label: 'What permissions should the user have?',
options: [
'read' => 'Read',
'create' => 'Create',
'update' => 'Update',
'delete' => 'Delete',
],
validate: fn (array $values) => ! in_array('read', $values)
? 'All users require the read permission.'
: null
);
Confirmation Dialog
use function Laravel\Prompts\confirm;
// Simple yes/no
$confirmed = confirm('Do you accept the terms?');
// With custom labels
$confirmed = confirm(
label: 'Do you accept the terms?',
default: false,
yes: 'I accept',
no: 'I decline',
hint: 'The terms must be accepted to continue.'
);
// Require "Yes"
$confirmed = confirm(
label: 'Do you accept the terms?',
required: true
);
Search (Searchable Select)
use function Laravel\Prompts\search;
$id = search(
label: 'Search for the user that should receive the mail',
placeholder: 'E.g. Taylor Otwell',
options: fn (string $value) => strlen($value) > 0
? User::whereLike('name', "%{$value}%")->pluck('name', 'id')->all()
: [],
hint: 'The user will receive an email immediately.',
scroll: 10
);
Suggest (Auto-completion)
use function Laravel\Prompts\suggest;
// Static options
$name = suggest('What is your name?', ['Taylor', 'Dayle']);
// Dynamic filtering
$name = suggest(
label: 'What is your name?',
options: fn ($value) => collect(['Taylor', 'Dayle'])
->filter(fn ($name) => Str::contains($name, $value, ignoreCase: true))
);
Multi-step Forms
use function Laravel\Prompts\form;
$responses = form()
->text('What is your name?', required: true, name: 'name')
->password(
label: 'What is your password?',
validate: ['password' => 'min:8'],
name: 'password'
)
->confirm('Do you accept the terms?')
->submit();
// Access named responses
echo $responses['name'];
echo $responses['password'];
// Dynamic forms with previous responses
$responses = form()
->text('What is your name?', required: true, name: 'name')
->add(function ($responses) {
return text("How old are you, {$responses['name']}?");
}, name: 'age')
->submit();
Progress Bar
use function Laravel\Prompts\progress;
// Simple usage
$users = progress(
label: 'Updating users',
steps: User::all(),
callback: fn ($user) => $this->performTask($user)
);
// With dynamic labels
$users = progress(
label: 'Updating users',
steps: User::all(),
callback: function ($user, $progress) {
$progress
->label("Updating {$user->name}")
->hint("Created on {$user->created_at}");
return $this->performTask($user);
},
hint: 'This may take some time.'
);
Loading Spinner
use function Laravel\Prompts\spin;
$response = spin(
callback: fn () => Http::get('http://example.com'),
message: 'Fetching response...'
);
Key Concepts
Input Types
Laravel Prompts provides several input types for different use cases:
- text() - Single-line text input with optional placeholder and validation
- textarea() - Multi-line text input for longer content
- password() - Masked text input for sensitive data
- confirm() - Yes/No confirmation dialog
- select() - Single selection from a list of options
- multiselect() - Multiple selections from a list
- suggest() - Text input with auto-completion suggestions
- search() - Searchable single selection with dynamic options
- multisearch() - Searchable multiple selections
- pause() - Pause execution until user presses ENTER
Output Types
For displaying information without input:
- info() - Display informational message
- note() - Display a note
- warning() - Display warning message
- error() - Display error message
- alert() - Display alert message
- table() - Display tabular data
Validation
Three ways to validate prompts:
Closure validation: Custom logic with match expressions
validate: fn (string $value) => match (true) { strlen($value) < 3 => 'Too short.', default => null }Laravel validation rules: Standard Laravel validation
validate: ['email' => 'required|email|unique:users']Required flag: Simple requirement check
required: true
Transformation
Use the transform parameter to modify input before validation:
$name = text(
label: 'What is your name?',
transform: fn (string $value) => trim($value),
validate: fn (string $value) => strlen($value) < 3
? 'The name must be at least 3 characters.'
: null
);
Terminal Features
- Scrolling: Configure visible items with
scrollparameter (default: 5) - Navigation: Use arrow keys, j/k keys, or vim-style navigation
- Forms: Press CTRL + U in forms to return to previous prompts
- Width: Keep labels under 74 characters for 80-character terminals
Reference Files
This skill includes comprehensive documentation in references/:
- other.md - Complete Laravel Prompts documentation including:
- All prompt types (text, password, select, search, etc.)
- Validation strategies and examples
- Form API for multi-step input
- Progress bars and loading indicators
- Informational messages (info, warning, error, alert)
- Tables for displaying data
- Testing strategies for console commands
- Fallback configuration for unsupported environments
Use view to read the reference file when detailed information is needed.
Working with This Skill
For Beginners
Start with basic prompts:
- Use
text()for simple input - Add
required: truefor mandatory fields - Try
confirm()for yes/no questions - Use
select()for predefined choices
Example beginner command:
$name = text('What is your name?', required: true);
$confirmed = confirm('Is this correct?');
if ($confirmed) {
$this->info("Hello, {$name}!");
}
For Intermediate Users
Combine multiple prompts and add validation:
- Use the
form()API for multi-step input - Add custom validation with closures
- Use
search()for database queries - Implement progress bars for long operations
Example intermediate command:
$responses = form()
->text('Name', required: true, name: 'name')
->select('Role', options: ['Member', 'Admin'], name: 'role')
->confirm('Create user?')
->submit();
if ($responses) {
progress(
label: 'Creating user',
steps: 5,
callback: fn () => sleep(1)
);
}
For Advanced Users
Leverage advanced features:
- Dynamic form fields based on previous responses
- Complex validation with Laravel validation rules
- Custom searchable prompts with database integration
- Transformation functions for data normalization
- Testing strategies for command prompts
Example advanced command:
$responses = form()
->text('Email', validate: ['email' => 'required|email|unique:users'], name: 'email')
->add(function ($responses) {
return search(
label: 'Select manager',
options: fn ($value) => User::where('email', 'like', "%{$value}%")
->where('email', '!=', $responses['email'])
->pluck('name', 'id')
->all()
);
}, name: 'manager_id')
->multiselect(
label: 'Permissions',
options: Permission::pluck('name', 'id'),
validate: fn ($values) => count($values) === 0 ? 'Select at least one permission.' : null,
name: 'permissions'
)
->submit();
Navigation Tips
- Arrow keys or j/k - Navigate options in select/multiselect
- Space - Select/deselect in multiselect
- Enter - Confirm selection or submit input
- CTRL + U - Go back to previous prompt (in forms)
- Type to search - In search/multisearch prompts
- Tab - Auto-complete in suggest prompts
Testing
Test commands with prompts using Laravel's built-in assertions:
use function Pest\Laravel\artisan;
test('user creation command', function () {
artisan('users:create')
->expectsQuestion('What is your name?', 'Taylor Otwell')
->expectsQuestion('What is your email?', '[email protected]')
->expectsConfirmation('Create this user?', 'yes')
->expectsPromptsInfo('User created successfully!')
->assertExitCode(0);
});
test('displays warnings and errors', function () {
artisan('report:generate')
->expectsPromptsWarning('This action cannot be undone')
->expectsPromptsError('Something went wrong')
->expectsPromptsTable(
headers: ['Name', 'Email'],
rows: [
['Taylor Otwell', '[email protected]'],
['Jason Beggs', '[email protected]'],
]
)
->assertExitCode(0);
});
Best Practices
Design Guidelines
- Keep labels concise (under 74 characters for 80-column terminals)
- Use
hintparameter for additional context - Set appropriate
defaultvalues when sensible - Configure
scrollfor lists with many options (default: 5)
Validation Strategy
- Use
required: truefor mandatory fields - Apply Laravel validation rules for standard checks (email, min/max, etc.)
- Use closures for complex business logic validation
- Provide clear, actionable error messages
User Experience
- Add placeholders to show expected input format
- Use
pause()before destructive operations - Show progress bars for operations taking >2 seconds
- Display informational messages after actions complete
- Group related prompts in forms for better flow
Performance
- Use
search()callbacks with length checks to avoid expensive queries:options: fn (string $value) => strlen($value) > 0 ? User::where('name', 'like', "%{$value}%")->pluck('name', 'id')->all() : [] - Limit database results with pagination or top-N queries
- Cache frequently-accessed option lists
- Use
spin()for HTTP requests and long operations
Common Patterns
User Registration Flow
$responses = form()
->text('Name', required: true, name: 'name')
->text('Email', validate: ['email' => 'required|email|unique:users'], name: 'email')
->password('Password', validate: ['password' => 'required|min:8'], name: 'password')
->submit();
Confirmation Before Destructive Action
$confirmed = confirm(
label: 'Are you sure you want to delete all users?',
default: false,
hint: 'This action cannot be undone.'
);
if (! $confirmed) {
$this->info('Operation cancelled.');
return;
}
Dynamic Multi-step Form
$responses = form()
->select('User type', options: ['Regular', 'Admin'], name: 'type')
->add(function ($responses) {
if ($responses['type'] === 'Admin') {
return password('Admin password', required: true);
}
}, name: 'admin_password')
->submit();
Batch Processing with Progress
$items = Item::all();
$results = progress(
label: 'Processing items',
steps: $items,
callback: function ($item, $progress) {
$progress->hint("Processing: {$item->name}");
return $this->process($item);
}
);
Resources
Official Documentation
- Laravel Prompts Documentation: https://laravel.com/docs/12.x/prompts
- Laravel Console Testing: https://laravel.com/docs/12.x/console-tests
Platform Support
- Supported: macOS, Linux, Windows with WSL
- Fallback: Configure fallback behavior for unsupported environments
Notes
- Laravel Prompts is pre-installed in Laravel framework
- Supports Laravel validation rules for easy integration
- Uses terminal control codes for interactive UI
- All prompts return values that can be used immediately
- Forms support revisiting previous prompts with CTRL + U
- Validation runs on every input change for immediate feedback
- Progress bars can be manually controlled or automated
Updating
This skill was generated from the official Laravel Prompts documentation. To refresh with updated information, re-scrape the Laravel documentation site.