Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Email Bundle Laravel Package

illarra/email-bundle

Illarra EmailBundle is a Symfony/PHP package that streamlines sending emails from applications. It offers configurable mail transport integration, templated message composition, and convenient services for delivering transactional and notification emails.

View on GitHub
Deep Wiki
Context7

Getting Started

Start with the go/no-go check, because for a Laravel developer the honest answer is that you cannot leverage this bundle day-to-day. It is a Symfony 2.x bundle, not a Laravel package: it registers through AppKernel::registerBundles(), resolves config through a Symfony Extension/Configuration tree, and renders with Twig. There is no ServiceProvider, no facade, no Blade namespace, and no package auto-discovery. composer require illarra/email-bundle on a modern Laravel project will either fail dependency resolution (Symfony ~2.3–~2.8, PHP 5.x/7.0-era constraints) or "succeed" only with --ignore-platform-reqs and a broken autoload graph. Don't force it.

The only scenario where you touch the code directly is maintaining an existing Symfony 2.7/2.8 app that already depends on it. In that case:

composer require illarra/email-bundle
// app/AppKernel.php
public function registerBundles()
{
    $bundles = [
        // ...
        new Illarra\EmailBundle\IllarraEmailBundle(),
    ];
}
# app/config/config.yml
illarra_email:
    default:
        from: { email: [email protected], name: "Acme" }
        reply_to: [email protected]
    theme:
        path: "%kernel.root_dir%/Resources/views/emails"
        layout: layout.html.twig

Where to look first (if reading it): DependencyInjection/Configuration.php is the authoritative list of options — docs are sparse — then Resources/config/services.xml for service IDs you can decorate or override. The public surface is small: a mailer service plus a Twig-rendered message object. Ten minutes of reading covers it.

First use case for a Laravel team: don't send an email with it — read it once, steal the design, and close the ticket. Then build the Laravel equivalent you actually need:

php artisan make:mail WelcomeMail --markdown=mail.welcome
php artisan vendor:publish --tag=laravel-mail   # theme in resources/views/vendor/mail
// app/Mail/WelcomeMail.php
class WelcomeMail extends Mailable implements ShouldQueue
{
    use Queueable, SerializesModels;

    public function __construct(public User $user) {}

    public function build(): self
    {
        return $this->theme('acme')
            ->subject('Welcome to Acme')
            ->markdown('mail.welcome', ['user' => $this->user]);
    }
}
Mail::to($user->email)->queue(new WelcomeMail($user));

That two-line controller call is the "service-based mailer" the bundle promised — Laravel already ships it.

Implementation Patterns

The bundle's value is conceptual, not executable in Laravel. Three of its ideas port cleanly:

1. Config-driven theming resolved in a base layout. The bundle's best idea is a theme.path + layout pair that every message inherits. Reproduce it in Blade rather than Twig:

// config/mail-theme.php
return [
    'default' => 'acme',
    'themes' => [
        'acme' => [
            'layout' => 'mail.layouts.acme',
            'from'   => ['address' => '[email protected]', 'name' => 'Acme'],
            'reply_to' => '[email protected]',
        ],
    ],
];
{{-- resources/views/components/mail/layout.blade.php --}}
@props(['theme' => config('mail-theme.default')])
<x-dynamic-component :component="'mail.'.$theme.'.wrapper" {{ $attributes }}>
    <x-mail.button href="...">Get started</x-mail.button>
</x-dynamic-component>

2. Template-driven messages with shared chrome. The bundle rendered content through a layout in Twig. In Laravel, factor the chrome into components (<x-mail.layout>, <x-mail.button>, <x-mail.panel>) and keep Markdown mailables for the body. Publish resources/views/vendor/mail and treat it as the single source of brand truth — one file to change when the design system moves.

3. CSS inlining as a pipeline step. This is the actually hard part, and the bundle's README glosses over it. Wire it into a base mailable so it never leaks into individual mailables:

abstract class ThemedMailable extends Mailable
{
    public function build(): self
    {
        return $this->withSymfonyMessage(function (Email $message) {
            $message->html((new CssInliner())
                ->inlineHtml($message->getHtmlBody()));
        });
    }
}

tijsverkoyen/css-to-inline-styles is already a transitive Laravel dependency — you don't add vendor weight.

4. Testability via swapping. The bundle advertises a "swappable mailer." Laravel's Mail::fake() is strictly better:

Mail::fake();
$this->post('/register', [...]);
Mail::assertQueued(WelcomeMail::class, fn ($m) => $m->hasTo('[email protected]'));

Add a rendered-HTML snapshot per mailable for regressions:

$html = (new WelcomeMail($user))->render();
$this->assertStringContainsString('class="btn-primary"', $html);
$this->assertMatchesSnapshot($html);

Workflow tips: queue every transactional mail (ShouldQueue + a Mail::to()->queue() call) so delivery latency never blocks a request; put the preview route behind app()->isLocal() and render each mailable to HTML for visual review — that replaces the bundle's Symfony profiler integration; and add a CI check that fails on un-inlined <style> blocks or missing plaintext alternatives.

Gotchas and Tips

  • The framework mismatch is the headline gotcha. No ServiceProvider, no auto-discovery (the composer.json type is symfony-bundle, so Laravel's discovery silently skips it), no Blade integration. Any roadmap line assuming drop-in usage should be closed now.
  • Don't attempt --ignore-platform-reqs. It "installs" but produces an autoload graph that will fail on the next PHP or Laravel upgrade and block unrelated work. That failure is silent until someone needs to deploy.
  • Archived means no CVE response. The bundle pins Swiftmailer and Twig versions with known vulnerabilities, and there is no security channel to alert you. For any email path processing user-influenced content — names in a welcome email, order lines in a receipt — that's an injection and template-escalation surface you cannot patch.
  • Twig ≠ Blade semantics. Layout inheritance, block overrides, and auto-escaping differ. Porting a Twig template line-for-line will produce subtle HTML that only breaks in Outlook. Rebuild in Blade; don't transliterate.
  • CSS inlining is not optional. Gmail strips <style> blocks. Inline everything, but keep a small <style> for responsive media queries — clients that strip styles will fall back to the inlined desktop layout.
  • Outlook and dark mode need bespoke work the bundle never addressed. Conditional comments (<!--[if mso]>), VML buttons, and dark-mode overrides via prefers-color-scheme are hand-written per template. The bundle gives you none of this; budget it explicitly rather than assuming "we integrated the email bundle" solved it.
  • Config paths don't translate. The bundle uses %kernel.root_dir%/Resources/views/emails. In Laravel use resource_path('views/mail'); don't copy the YAML — rewrite the theme config natively.
  • Sender defaults differ. Symfony config wants from: { email, name } and a separate reply_to; Laravel resolves config('mail.from') and per-mailable $from/$replyTo. Map them, don't merge them.
  • Debugging path: render to HTML ($mailable->render() in Tinker, or a dev-only preview route) before you ever hit "send." Inspecting the raw HTML is ten times faster than debugging a delivery provider. Snapshot tests catch the dark-mode and Outlook regressions you can't see in a browser.
  • Extension points if you must fork: decorate the bundle's mailer service, override its config tree, or supply a custom Twig loader. All are Symfony-specific and transfer nowhere — a bad learning investment for a Laravel engineer.
  • Bus factor one, forever. The repo is archived with one star and zero dependents. Any fork is yours to maintain indefinitely with no upstream to rebase against. Capture the theming idea, write down the decision, and move the effort into an owned email component library instead.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package