How to Use Bundles in a Symfony Web Application

Introduction

Symfony is built around a simple but powerful idea: everything is a bundle. A bundle is a self-contained package of code — controllers, entities, services, and templates — that can be reused across multiple projects.

In this guide, we’ll walk through how bundles work, how to create your own, and how they fit into a modern Symfony 7 application.

What Is a Bundle?

In Symfony, a bundle is similar to a plugin in other frameworks, but more structured. Bundles can contain anything: configuration, routes, services, entities, forms, and templates. Each bundle is represented by a PHP class that extends Symfony\Component\HttpKernel\Bundle\Bundle.


// src/CustomerBundle/CustomerBundle.php
namespace App\CustomerBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class CustomerBundle extends Bundle
{
}
    

The presence of this class tells Symfony that this directory is a bundle that should be bootstrapped during the kernel initialization.

Bundle Folder Structure

A typical bundle mirrors the structure of a full Symfony app:


src/
└── CustomerBundle/
    ├── Controller/
    │   └── CustomerController.php
    ├── Entity/
    │   └── Customer.php
    ├── Repository/
    │   └── CustomerRepository.php
    ├── Resources/
    │   ├── config/
    │   │   └── routes.yaml
    │   └── views/
    │       └── customer/
    │           └── list.html.twig
    ├── Service/
    │   └── CustomerNotifier.php
    └── CustomerBundle.php
    

Everything related to customer management — code, templates, configuration — lives neatly inside its own namespace.

Creating a Controller Inside Your Bundle

Let’s add a simple controller that lists all customers.


// src/CustomerBundle/Controller/CustomerController.php
namespace App\CustomerBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/customers')]
class CustomerController extends AbstractController
{
    #[Route('/', name: 'customer_list')]
    public function list(): Response
    {
        // In a real app, you'd fetch this from the database
        $customers = [
            ['name' => 'Alice', 'email' => 'alice@example.com'],
            ['name' => 'Bob', 'email' => 'bob@example.com'],
        ];
        return $this->render('@Customer/customer/list.html.twig', [
            'customers' => $customers,
        ]);
    }
}
    

The Twig template lives inside the bundle under: Resources/views/customer/list.html.twig

Example Twig Template


{# src/CustomerBundle/Resources/views/customer/list.html.twig #}

Customer List


  {% for customer in customers %}
    
  • {{ customer.name }} — {{ customer.email }}

  {% endfor %}
    

Symfony automatically resolves @Customer to your bundle’s view path, thanks to the bundle namespace registration.

Registering Your Bundle

In Symfony 7, bundles can be registered automatically using Symfony Flex. If you need to register it manually, open config/bundles.php:


// config/bundles.php
return [
    Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
    App\CustomerBundle\CustomerBundle::class => ['all' => true],
];
    

Once registered, Symfony treats it as a first-class part of your application.

Adding Services to Your Bundle

Services inside the bundle can be auto-configured and autowired using a services.yaml file:


# src/CustomerBundle/Resources/config/services.yaml
services:
  App\CustomerBundle\:
    resource: '../../*'
    exclude: '../../{Entity,Tests,Resources}'
    autowire: true
    autoconfigure: true
    

Then import this file from your main configuration:


# config/services.yaml
imports:
  - { resource: '@Customer/Resources/config/services.yaml' }
    

Reusing Your Bundle Across Projects

The real magic of bundles appears when you start reusing them. You can move src/CustomerBundle into its own repository, add a composer.json, and install it like any PHP package.


{
  "name": "acme/customer-bundle",
  "type": "symfony-bundle",
  "autoload": {
    "psr-4": { "Acme\\CustomerBundle\\": "" }
  },
  "require": {
    "php": ">=8.2",
    "symfony/framework-bundle": "^7.0"
  }
}
    

After publishing it to Packagist or GitHub, you (or others) can reuse it in any Symfony project:


composer require acme/customer-bundle
    

Conclusion

Bundles are one of Symfony’s most powerful concepts. They help you organize code logically, promote reuse, and maintain clean architecture. By structuring features as independent bundles, your applications become modular and scalable by design.

Whether you’re building a small app or a complex CRM, bundles will keep your Symfony projects elegant, consistent, and easy to maintain.

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Please share this article on your favorite website or platform.