Contributing to Laravel: A Practical Guide to Your First Pull Request

Mastering the Laravel Contribution Workflow

Contributing to a massive ecosystem like the

feels intimidating, but the process follows a logical, highly structured path. Every significant addition starts with a clear idea and a thorough check of existing work. Before writing a single line of code, search through closed and unmerged pull requests on
GitHub
. This step prevents you from duplicating work or reviving ideas that the maintainers have already rejected for specific architectural reasons. If your idea fills a genuine gap—like adding interactive prompts to an existing command—you are ready to move forward.

Setting Up for Success: Forking and Cloning

You must work on the correct branch to ensure your code is even considered. For the

, this is typically the current stable development branch, such as 11.x. Start by forking the official repository to your own account and then cloning it locally. To test your changes within a real-world context, link your local fork to a fresh
Laravel Framework
application. You can do this by modifying the composer.json of a test project to point its repository source to your local path. This setup allows you to see how your changes affect the
PHP Artisan
CLI in real-time.

The TDD Approach to Framework Features

When modifying internal commands like make:notification, a Test-Driven Development (TDD) workflow is your best friend. Start by identifying the relevant test class, such as NotificationMakeCommandTest. Write a failing test that simulates a user calling the command without arguments and then answering prompts.

public function test_it_prompts_for_markdown_template()
{
    $this->artisan('make:notification')
         ->expectsQuestion('What should the notification be named?', 'ExportFinished')
         ->expectsConfirmation('Would you like to create a markdown view?', 'yes')
         ->expectsQuestion('What should the markdown view be named?', 'export-finished')
         ->assertExitCode(0);
}

By defining the expected interaction first, you create a roadmap for your implementation. This ensures that the new feature behaves exactly as intended before you touch the core logic.

Implementing Interactive Prompts

To add interactive prompts to a command, you need to hook into the afterPromptingForMissingArguments method. This method runs after the basic arguments (like the class name) are collected. You can use the setOption method to inject user input into the command's existing logic.

protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
{
    if ($this->didReceiveOptions($input)) {
        return;
    }

    $markdown = confirm('Would you like to create a markdown view?');

    if ($markdown) {
        $input->setOption('markdown', text(
            label: 'What should the markdown view be named?',
            placeholder: 'mail.invoice-paid'
        ));
    }
}

Using the

library makes these interactions beautiful and consistent with the rest of the framework. Always include a placeholder to guide the user on the expected naming convention.

Common Gotchas and the PR Process

Even with passing local tests,

might fail due to styling issues or environmental differences.
Laravel Framework
uses strict
PHP
styling; however, minor style fixes are often handled automatically upon merging. A more common issue is file cleanup. If your test creates files, ensure they are listed in the $files property of the test class so they are deleted after the test run.

When submitting the PR, provide a descriptive title and a screenshot of the CLI interaction. Explain the benefit to the end-user clearly. Remember that

and the team must maintain this code forever; simplicity is the highest virtue. If a PR is rejected, do not take it personally—maintainers must say "no" frequently to keep the framework lean and stable.

4 min read