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

Swiftmarkbundle Laravel Package

kassoulet/swiftmarkbundle

SwiftMarkBundle brings SwiftMark integration to Symfony, simplifying Markdown rendering for templates, services, and Markdown-based emails. Install via Composer, configure the bundle, and add clean Markdown workflows to your app without custom wiring.

View on GitHub
Deep Wiki
Context7

Getting Started

Correct the premise before you install anything. Despite being evaluated in a Laravel context, kassoulet/swiftmarkbundle is a Symfony bundle built on SwiftMailer. There is no service provider, no facade, no config/swiftmark.php, and no Markdown mailable hook. Laravel's mail stack (Illuminate\Mail) does not consume Bundle subclasses, DependencyInjection/Extension classes, or Symfony service YAML. The realistic Laravel outcome is one of two things: pull the underlying renderer class out and use it as a library, or — much more likely — rebuild the capability in an afternoon on league/commonmark and Laravel's native Markdown mailables.

Verify installability first. The name may not resolve on Packagist, and even if it does, its require block likely pins SwiftMailer and an older Symfony major, which will collide with a modern Laravel app:

composer show kassoulet/swiftmarkbundle --all

If that returns nothing, add the VCS repo and pin a commit rather than a floating branch:

{
  "repositories": [
    { "type": "vcs", "url": "https://github.com/Jb-31/KassouletSwiftMarkBundle" }
  ],
  "require": { "kassoulet/swiftmarkbundle": "dev-master" }
}

Expect dependency conflicts. SwiftMailer reached end-of-life in November 2021 and Laravel 9+ dropped it. If Composer refuses to resolve, that is the package telling you the answer.

Where to look first, in order:

  1. composer.json — symfony/* and swiftmailer/swiftmailer constraints. This tells you the target Symfony version and confirms the EOL transport.
  2. Resources/config/services.yml (or config/services.yaml) — the authoritative list of service IDs, constructor arguments, and tags. Almost every "how do I use this" question is answered here, not in the README.
  3. DependencyInjection/Configuration.php — actual config keys and defaults (template path, Markdown flavor, layout wrapping).
  4. The renderer class itself (something like Kassoulet\SwiftMark\Renderer) and any Swift_Events_*Listener / Swift_Plugins_DecoratorPlugin subclass — the listener, if present, is the intended send-pipeline hook.

First use case — render one Markdown string to HTML, in Laravel, without the bundle:

// AppServiceProvider::register() — direct use of the bundle's renderer as a plain class
$this->app->singleton('swiftmark', function () {
    // Copy constructor args verbatim from the bundle's services.yml.
    return new \Kassoulet\SwiftMark\Renderer(/* markdown parser, options, theme path */);
});
$html = app('swiftmark')->render("# Hello\n\n**World**");

If that produces HTML, you understand the whole capability. The native Laravel equivalent is shorter and maintained:

use League\CommonMark\CommonMarkConverter;

$html = (new CommonMarkConverter([
    'html_input' => 'strip',
    'allow_unsafe_links' => false,
]))->convert("# Hello\n\n**World**")->getContent();

That is effectively the package. Budget a day to confirm it and you can close the evaluation.

Implementation Patterns

Pattern 1 — Treat the bundle as a class, not a dependency

The only thing worth extracting is the renderer. Register it as a singleton in AppServiceProvider, copying constructor arguments from the bundle's services.yml. This keeps the dependency surface to one class you can replace later, and avoids dragging Symfony DI into a Laravel app.

// AppServiceProvider::register()
$this->app->singleton(MarkdownRenderer::class, function () {
    return new MarkdownRenderer(new CommonMarkConverter([...]));
});

Do not try to load the Bundle class or its extension. That path leads to manually bootstrapping a Symfony container, which is not a thing you want in a Laravel app.

Pattern 2 — Wrap it in a Mailable

If you do adopt the renderer, hide it behind a Mailable so callers never touch Markdown directly:

class WelcomeEmail extends Mailable
{
    use Queueable, SerializesModels;

    public function __construct(public User $user) {}

    public function build()
    {
        $md = file_get_contents(resource_path('mail/welcome.md'));
        $html = app('swiftmark')->render($md);

        return $this->subject('Welcome')
            ->html($html)
            ->text($this->toPlainText($html));
    }

    private function toPlainText(string $html): string
    {
        return (new \League\HTMLToMarkdown\HtmlConverter())->convert($html);
    }
}

The ->text() half is where most Markdown-to-email implementations quietly break: strip_tags() destroys links and list structure. Use an HTML→text converter, or render the source twice (Markdown→text via a plain renderer, Markdown→HTML via the converter).

Pattern 3 — Use Laravel's native Markdown mailables (the recommended path)

Laravel has shipped Markdown mailables since 5.7, backed by league/commonmark. This is the idiomatic equivalent and gets security patches:

public function build()
{
    return $this->markdown('mail.welcome', ['user' => $this->user]);
}

The Blade view at resources/views/mail/welcome.blade.php contains Markdown with Blade interpolation, and Laravel renders both HTML and plain-text parts. Extensions (tables, footnotes, strikethrough) are configurable through the mail.markdown config in config/mail.php.

Pattern 4 — If you are actually on Symfony

Register the bundle in config/bundles.php, configure it under config/packages/, and use the tagged SwiftMailer decorator/listener if one exists so rendered output is applied during send() rather than by manual render() calls. This is the only context where the package's design makes sense — and only if Symfony Mailer migration is genuinely off the table.

Integration tips

  • Golden-file tests. Before you commit to any renderer, snapshot rendered HTML for a corpus of representative emails (headers, lists, tables, links, code blocks). Compare the bundle's output to league/commonmark's. If they match, the bundle adds nothing.
  • Sanitize input. If Markdown bodies are user-editable at all, set html_input => 'strip' and allow_unsafe_links => false, or run output through HtmlSanitizer. The bundle is unmaintained; do not assume it does this.
  • Keep plain-text in sync from one source. Author in Markdown once, render twice, or render HTML and convert. Never maintain a separate hand-written .txt template.
  • Queue and test with the array/log transport. The rendering concern is stateless and CPU-bound; mail delivery is the bottleneck and lives in the transport, not here. Use Mail::fake() in tests so you assert on rendered content, not on sends.

Gotchas and Tips

  • Framework mismatch is disqualifying. A Symfony Bundle cannot be installed into Laravel. Anything that looks like "integration" is you reading the source and re-implementing. Treat that as the default plan, not a fallback.
  • SwiftMailer is EOL (Nov 2021). Dropped from Symfony 6 and Laravel 9+. Any new integration adds surface area to a transport you should be migrating away from. This is the single strongest argument against adoption.
  • Zero stars, zero dependents, zero score, single maintainer. No issue-tracker signal, no CI visibility, no one to file a bug. You are the maintenance plan. Vendor the renderer into app/Support/ if you keep it, rather than leaving it as a Composer line item nobody can justify in six months.
  • Service IDs are not documented. kassoulet.swiftmark.renderer (or whatever the real ID is) is only known from services.yml. Do not guess; read the file. If the bundle renames it in a minor release, nothing in your app catches the break until runtime.
  • Markdown rendering is an injection surface. Links (javascript:), raw HTML passthrough, and image sources are all real attack vectors. An unmaintained parser will not have kept pace. Configure commonmark conservatively regardless of which renderer you use.
  • Plain-text drift is silent. strip_tags() output looks fine in logs and terrible in mail clients. Test the text part explicitly — inspect the text/plain MIME part, not the debug HTML.
  • Composer resolution failures are a signal, not an obstacle. If symfony/* and swiftmailer/swiftmailer conflict with your lockfile, do not add --ignore-platform-reqs or a shim. That is the package correctly telling you it does not belong in a modern stack.
  • Debugging: dump the rendered HTML before it hits the transport (dd($html) in a local-only branch, or write to a file), and use MAIL_MAILER=log so you can diff what actually would have been sent. Comparing rendered output to a hand-written HTML email is the fastest way to spot a broken conversion.
  • Extension points, if you build in-house: league/commonmark extensions for tables, footnotes, autolinks, and strikethrough are config flags. Add them as needed — that is the entire feature surface you would be missing by not adopting this bundle.
  • Migration posture: sequence this as evaluate → reimplement natively → close, not evaluate → adopt → harden. The package's only durable contribution is its behavior spec: which Markdown dialect, which extensions, how the plain-text part is generated, how the layout wraps the body. Capture that in a short document and write the replacement.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo