hampe/inky
Laravel package for Inky, Zurb Foundation's email templating language. Build responsive HTML emails with Inky components and compile them into email-client-friendly markup, making transactional and marketing emails easier to maintain.
Architecture fit. Unchanged in shape. hampe/inky remains a single-purpose transform: Inky markup in, table-based email HTML out, mapped to one seam between Blade rendering and transport. Still no service provider, no facade, no config, no Illuminate coupling — we own the wiring. What the release does change is the dependency topology inside that seam. The 1.3.6.2 notes state "Updated to PHPHtmlParser 1.7.0," which corrects an assumption in the prior assessment: the parser is not libxml/DOMDocument, it is a third-party PHP HTML parser. That is material. It largely retires the XXE/LIBXML_NOENT/entity-substitution concern (a pure-PHP parser does not resolve external entities the way libxml does), but it substitutes a different problem: we now have two aging dependencies in the mail path, one of which (the parser) we did not previously scope, price, or review. The architectural question is still "does the Inky grammar fit our email program," but the technical question is now "what is the full transitive tree, and who owns the parser."
Integration feasibility. Still high mechanically: MIT, Composer-installable, one class, one transform(string): string. Two feasibility notes are revised. First, the "last release 2016-08-30, therefore frozen" premise no longer holds cleanly — 1.3.6.2 exists, references tracked issues (#6, #7), and ships a dependency bump. That is evidence of a live, if sporadic, maintainer. Second, the PHP-version question is now sharper, not softer: pinning paquettg/php-html-parser (or equivalent) at 1.7.0 — itself an old line — is the most likely source of a PHP 8.2/8.3 constraint conflict, and it may block us before Inky's own composer.json does. The fork-or-vendor decision is unchanged in method but the blast radius is larger: a fork now means owning the parser bump too, and a widen-constraints patch may need to reach into the transitive dependency rather than just the top-level manifest.
Technical risk.
<style> tags is a fidelity fix, not a fidelity audit. Quarterly Litmus/Email on Acid validation remains mandatory.Key questions.
composer.json constrain for PHP and for the HTML parser, and does that tree resolve on PHP 8.2/8.3?<style> blocks through to transport, or does it still assume a separate CSS inliner? Who owns that stage?Stack fit. Unchanged: Laravel 10/11, PHP 8.2+, chain of Blade render → Inky transform → CSS inline → transport, with Inky behind an EmailTransformer interface. The interface is now doing more work than originally scoped — it must isolate two volatile dependencies, not one. Keep the transform stage narrow enough that a swap to MJML or Blade partials is a container binding change.
Migration path. Same six steps, with the fork decision softened rather than reversed:
The lock-in warning stands and is now sharper: pin 1.3.6.2 exactly, not ^1.3. The 1.3.6.0 nested-spacer regression is a worked example of why a floating constraint on this package is unsafe.
Compatibility. Two axes, unchanged in kind. Runtime: verify the full tree — Inky plus PHPHtmlParser 1.7.0 — resolves against our lockfile, and note that this release tightens the parser constraint, so our resolution surface moved. Visual: diff 1.3.6.2 output against both current production and pre-1.3.6.0 output, specifically on nested spacers and <style> handling; both are the exact surfaces this release touches.
Sequencing. Unchanged and reinforced. Inliner first (actively maintained, independently valuable), transformer second. Add one step: run the golden-file corpus against 1.3.6.2 before the client-matrix render, so the two known regression surfaces are cleared cheaply.
Maintenance. The headline cost drops a notch — we are no longer the maintainer of record on day one — but the budget line does not disappear, it changes shape. We now need: a pinned version, a watch on upstream releases (with the explicit assumption that a point release may contain a layout regression), a quarterly PHP-compat check on two packages, and an SBOM entry flagging the parser as well as Inky. If upstream goes quiet again, the fork obligation returns unchanged, and it is now a two-package fork. Name an owner anyway; the probability of needing them is lower, the cost of not having them is the same.
Support. Still no vendor and no SLA, but there is now evidence of responsiveness — issues #6 and #7 were tracked and closed. That is a meaningful upgrade over "no issue triage at all," and it is the single strongest argument in this release. It is not a support contract; do not let a two-item changelog get read as one. Regulated and PII-bearing notifications should still route through templates we can fully reason about and test.
Scaling. Unchanged and still effectively free. CPU-bound, sub-millisecond, fully cacheable on a hash of Inky source + library version + parser version. That cache key now needs the parser version added, since 1.3.6.2 changes emitted output for some inputs. Keep personalization as post-transform token substitution.
Failure modes.
Ramp-up. Developer velocity unchanged — Inky markup is learnable in an hour and is a modest win for lifecycle teams authoring templates. The fork-owner skill investment is deferred, not eliminated. Revised honest TPM recommendation: the abandonment argument no longer carries the decision on its own — a maintained patch release that closes two real layout bugs is a genuine positive signal. But it is one data point, and it arrives attached to a demonstrated regression in the immediately preceding point release and a newly introduced transitive dependency. Run the one-week spike, pin 1.3.6.2 exactly, require the golden-file corpus and client matrix as preconditions rather than follow-ups, and choose between Inky and MJML/partials purely on measured client fidelity and 24-month ownership cost. If Inky wins, adopt upstream pinned — not a fork — and re-evaluate the fork question at the next release, or at twelve months of silence, whichever comes first.
How can I help you explore Laravel packages today?