zbateson/mail-mime-parser
A testable, PSR-compliant PHP mail MIME parser for RFC 822/2822/5322 messages. An alternative to imap* functions and Pear libraries, it parses strings, resources, or PSR-7 streams into messages with forgiving, standards-based handling. Requires PHP 8.1+.
Build vs. buy for any email-ingestion feature. This package answers the "parse" half of every inbound-email roadmap item. It is a well-scoped buy that removes the nastiest 20% of the work (RFC 2045/2047 encoded words, RFC 2231 split parameters, nested multipart boundaries, transfer-encoding decoding, charset handling) while leaving the parts you should own (transport, storage, routing, business logic) in your codebase.
AddressHeader::getAddresses(), getPersonName()), subject, X- custom headers, text vs. HTML bodies, and attachments with filenames and decoded content streams. That maps directly to a data model: sender, subject, body_text, body_html, attachments[].getAttachmentPart(n), getContentStream(), and saveContent($path) mean attachments can be streamed straight to S3 or local disk without buffering whole files in memory — a concrete cost and reliability decision, not just a convenience.mmp-crypt-smime, mmp-crypt-gpg) let the parser auto-detect and decrypt S/MIME or PGP/MIME. If you're selling into healthcare, legal, or finance, "we can ingest signed/encrypted mail" is a roadmap item you can scope as configuration rather than a quarter of engineering.imap_* functions (procedural, hard to unit test, requires the IMAP extension, awkward to feed a stored string), PEAR Mail_mime (dated), or hand-rolling regexes against boundary= (a recurring source of production incidents). Choosing this package is a defensible "don't roll your own parser" decision.StreamInterface support and PSR-4/PSR-compliant DI mean it slots into a modern Laravel container instead of fighting it.parse() accepts a raw string, so fixtures are just .eml files in your test suite. That directly supports CI-level regression coverage for the "customer sent us a weird email" class of bug.maxMimePartCount, maxMimePartDepth, maxHeaderCount, maxMessageHeaderCount, maxMessageHeaderSizeBytes, maxMessageHeaderTokenCount). If you accept mail from untrusted senders, you must pin a patched version and tune those limits — that's a real backlog item, not a formality.Adopt when:
webklex/php-imap, a webhook from Postmark/Mailgun/SES, an .eml file, or a raw request body).MailParserService wrapper and binding it in a service provider.Look elsewhere, or scope it down, when:
Mail facade. Don't expect it to replace them.imap_* reading functions, not to a full IMAP library.config/. Expect to write that glue — a day of work, not a blocker, but budget it honestly.For executives — the one-paragraph version:
Inbound email is a feature request we keep deferring because "parsing email properly" sounds like a bottomless pit. It isn't, if we buy the parsing layer instead of building it. zbateson/mail-mime-parser is a mature, permissively licensed (BSD-2-Clause) PHP library that turns a raw email into structured fields — sender, subject, body, attachments — including the ugly real-world cases that break naive implementations. It is actively maintained (recent releases with security hardening), free, and has no lock-in: the BSD license means we can fork it if we ever need to. Adopting it converts a multi-sprint infrastructure risk into a two-week feature delivery.
For engineering — why this is the right dependency:
parse($string) and Message::from($string) mean fixtures are .eml files, not mocks of a mail server. Our test suite gets better, not worse.MailParserService plus a service-provider binding is the entire integration.getContentStream() / saveContent() avoids loading large attachments into memory — a direct win on worker memory ceilings.^4.0.6 or later, override the defaults via DI config for our expected message sizes, run untrusted input through a queue with a timeout, and never construct messages from unvalidated user input.For the business — what it unlocks and what it costs:
Recommendation: Adopt for the parsing layer of the next email-ingestion feature. Do not adopt it as a mail-sending or mailbox-management solution. Wrap it behind an internal interface so the choice remains reversible.
How can I help you explore Laravel packages today?