Installation Add the bundle via Composer:
composer require symfony/maker-bundle --dev
Enable it in config/bundles.php:
return [
// ...
Symfony\MakerBundle\MakerBundle::class => ['dev' => true, 'test' => true],
];
First Command
Run the make:controller command to generate a basic controller:
php bin/console make:controller Blog/PostController
Follow prompts to customize (e.g., route path, template, CRUD actions).
Where to Look First
php bin/console list make to see available generators.vendor/symfony/maker-bundle/Resources/skeleton for boilerplate logic.CRUD Generation
Use make:crud for full-stack scaffolding (controllers, forms, templates, and entities):
php bin/console make:crud Blog/Post --field="title:string" --field="content:text"
--format=json for API-only CRUD.Customizing Generators
Override default templates by copying skeletons from vendor to config/packages/symfony_maker/:
mkdir -p config/packages/symfony_maker
cp vendor/symfony/maker-bundle/Resources/skeleton/* config/packages/symfony_maker/
Edit files like controller.php.twig to modify generated code.
Integration with Existing Code
make:entity to add fields to existing Doctrine entities:
php bin/console make:entity Blog/Post --add
php bin/console make:form Blog/PostType --fields="title:text,content:ckeditor"
Testing
Generate test classes with make:test:
php bin/console make:test Blog/PostControllerTest
Supports PHPUnit and Pest frameworks.
Automating with Custom Commands Extend the bundle by creating custom makers (see Custom Makers).
php bin/console make:fixtures Blog/PostFixtures
make:crud with --format=json for API-first projects.make:form to leverage Symfony UX components (e.g., Turbo, Stimulus):
php bin/console make:form Blog/PostType --fields="title:text,content:stimulus"
--env=test to generate test-specific code (e.g., test controllers or fixtures).Template Overrides
config/packages/symfony_maker/ may be overwritten during updates.post-update-cmd in composer.json to preserve overrides:
"scripts": {
"post-update-cmd": [
"php bin/console cache:clear",
"cp -r vendor/symfony/maker-bundle/Resources/skeleton/* config/packages/symfony_maker/ 2>/dev/null || true"
]
}
Backward Compatibility
Doctrine Entity Conflicts
make:entity on an existing entity may cause conflicts if fields already exist.--add to append fields or manually merge changes.Command Argument Changes
--field vs. --fields).Caching Issues
php bin/console cache:clear
-v for debugging:
php bin/console make:controller -v Blog/PostController
--dry-run to preview changes without writing files (if supported by the command).{{ dump() }} to .twig templates to inspect variables during generation.Custom Makers
Create reusable generators by extending AbstractMaker:
// src/Maker/CustomCommandMaker.php
namespace App\Maker;
use Symfony\Bundle\MakerBundle\Maker\Generator;
use Symfony\Bundle\MakerBundle\InputConfiguration;
use Symfony\Bundle\MakerBundle\Maker\MakerInterface;
class CustomCommandMaker implements MakerInterface
{
public function configureOptions(InputConfiguration $config): void
{
$config->setName('make:custom-command');
}
public function generate(InputConfiguration $config, Generator $generator): void
{
$generator->generateFile(
'src/Command/CustomCommand.php',
'custom_command.php.twig',
['command_name' => $config->getArgument('name')]
);
}
}
Register it in config/packages/symfony_maker.php:
makers:
App\Maker\CustomCommandMaker:
command: make:custom-command
Event Listeners
Hook into the maker.generation event to modify generated files:
// src/EventListener/MakerListener.php
namespace App\EventListener;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Bundle\MakerBundle\Event\MakerEvent;
#[AsEventListener(event: 'maker.generation', method: 'onGeneration')]
class MakerListener
{
public function onGeneration(MakerEvent $event): void
{
$event->getGenerator()->addFileToGenerate(
'custom_file.php',
'custom_template.twig',
['custom_var' => 'value']
);
}
}
Environment-Specific Logic
Use InputConfiguration to conditionally generate code based on environment:
public function generate(InputConfiguration $config, Generator $generator): void
{
if ($config->getOption('env') === 'test') {
$generator->generateFile('tests/TestController.php', 'test_controller.twig');
}
}
Alias Commands: Add shortcuts to config/packages/symfony_maker.php:
aliases:
mc: make:controller
me: make:entity
Now use php bin/console mc Blog/PostController instead of the full command.
Git Ignore: Exclude generated files from version control by adding to .gitignore:
/var/cache/*
/config/packages/symfony_maker/*
IDE Support: Use // @formatter:off and // @formatter:on in generated files to preserve formatting in your IDE.
Symfony Flex Recipes: Leverage Symfony recipes to automate post-installation tasks (e.g., copying templates).
How can I help you explore Laravel packages today?