voku/css-to-inline-styles
voku/css-to-inline-styles converts CSS rules into inline style attributes on HTML elements, making it useful for email templates and clients that strip or ignore style tags. It is a PHP library for reliably inlining stylesheets directly into markup.
Transactional email rendering fidelity. Whether your app's email templates render correctly in Gmail, Outlook 2016–2021, and Apple Mail depends on CSS being inlined into style attributes. This package is one implementation of that capability, so it sits underneath decisions like "do we support rich branded transactional email?" vs. "do we ship plain-text-plus-basic-HTML and accept a lower visual ceiling?"
Build vs. buy for a commodity utility. CSS inlining looks trivial and isn't: specificity resolution, !important, shorthand expansion, <style> block stripping, and media-query preservation are all edge-case farms. This package informs the buy/build call — and the more important sub-decision, which implementation owns the job.
Duplicate dependency audit. In a Laravel codebase this capability is almost certainly already present transitively. Adopting this package is a decision to run two inliners, or to standardize on this one and remove the other. That's a dependency-graph decision with a real maintenance tail, not a feature decision.
Email template authoring workflow. If the PM is deciding whether designers author in raw HTML+CSS (inlined at send time), in MJML, or in a hosted ESP's editor, this package only supports the first path. That constrains who can edit templates and how brand changes flow through the roadmap.
Multi-tenant / white-labeling roadmap. If customers can supply brand CSS, inlining becomes a per-request transformation with untrusted input — a security and performance surface, not just a rendering helper. Worth scoping before promising "custom branding" on the roadmap.
Responsive email positioning. Inlining is fundamentally at odds with media queries: the clients that strip <style> blocks are the ones that need inlining, and media queries only work in <style> blocks. Committing to this approach effectively commits the product to a single-column, fluid or hybrid layout, and rules out a "fully responsive email" claim without additional tooling.
Consider it when all of the following hold:
NOASSERTION on a 19-star fork with zero dependents is a genuine blocker for many orgs; you need a human to confirm provenance and terms before this reaches production).Look elsewhere when:
For executives (one paragraph). This is a small, narrow utility that fixes a specific, unglamorous problem: emails look broken in some inboxes because certain clients ignore stylesheets, and this package rewrites the HTML so they don't. It is not a strategic capability — it's plumbing. The reason to raise it at all is that it's a choice between plumbers: we very likely already ship an equivalent, better-supported library inside our existing framework, and this candidate is a low-adoption fork with unclear licensing. My recommendation is to treat this as a reference implementation rather than a procurement: confirm what we already have, verify it against a real client rendering matrix, and only revisit if it fails a concrete case. No budget ask, no roadmap shift; the product value is in the verification work, not the dependency.
For engineering (the honest version). The technical need is real and the problem domain is deceptively fiddly — specificity, !important, shorthand properties, <style> extraction, and the inherent tension between inlining and media queries. But the decision is not "inline or not"; it's "which inliner, and can we delete one instead of adding one." In a Laravel codebase, tijsverkoyen/css-to-inline-styles arrives with the framework and is exercised by every markdown mail send — installing voku/css-to-inline-styles alongside it means two parsers, two sets of edge cases, and a 19-star dependency with zero dependents and an unasserted license sitting on the critical path of customer-facing email. If there's a concrete rendering bug the incumbent misses, bring that bug — a reproducing template and the failing client — and we'll evaluate the fork on the merits of that case. Otherwise the engineering ask is: inventory existing inliners, build a five-client rendering check, and close the ticket.
The one-line framing for the room: "We don't need this package; we need to know which inliner we already have and whether it's good enough. Let's spend a day proving that before we spend a dependency on it."
How can I help you explore Laravel packages today?