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.