coolms/dtmpl
A sandboxed template language for non-PHP authors, with lexer, parser, AST and runtime, plus extensible widgets, filters and loaders. No PHP, filesystem or arbitrary calls—framework-optional, with a Symfony bundle available.
Architecture fit. DTMPL is a standalone lexer/parser/AST/runtime with explicitly no HTTP kernel and no DI container. That is a clean separation and a genuine architectural strength for a package — the engine does one thing and exposes seams (widgets, filters, constants, loaders) that the host fills. For a Laravel shop, however, "framework-optional" means "framework-unintegrated": there is no service provider, facade, config file, or Blade-style directive layer. All of that is ours to write. The Symfony path is covered by coolms/dtmpl-bundle; the Laravel path is not, and the absence of any dtmpl-laravel package is a meaningful integration cost, not a rounding error.
Integration feasibility. The engine itself should bind cleanly — instantiate the engine in a singleton, register widgets from a config array, wire filters to app services. The friction points are peripheral and predictable: the package depends on psr/cache (PSR-6), while Laravel's cache repository is PSR-16, so a PSR-6 adapter is required for the engine's caching layer. It also pulls symfony/property-access and symfony/translation-contracts, which are small but not native to a Laravel install. The PHP ^8.5 requirement is the dominant feasibility constraint: current Laravel releases target PHP 8.2–8.4, so a standard Laravel application cannot install this package without upgrading the runtime ahead of the framework's supported matrix. That single line in composer.json likely explains the zero dependents more than any design flaw.
Technical risk. High and concentrated:
Key questions.
Stack fit. DTMPL fits a specific Laravel shape: content-heavy applications with a CMS or multi-tenant surface where non-developers author templates and where PHP-in-template is unacceptable. It is a poor fit for ordinary application views, where Blade's zero-cost integration, component model, and first-party documentation make the switching cost indefensible. If the requirement is genuinely "designers ship templates without touching PHP," DTMPL is a defensible option; if the requirement is "we'd like nicer templates," it is not.
Migration path. Do not migrate Blade views. Target the narrow lane where a template language is already the plan — CMS page bodies, email/notification layouts, tenant-specific landing pages, marketing fragments — and leave application views in Blade. Realistically the comparison set is not Blade but Twig, Antlers/Statamic, or a Handlebars-style layer, so the migration is from whichever of those is currently in play, not from Laravel's default. Plan for a dual-render period: render existing content through the current path and new content through DTMPL, with a shadow comparison on a sample before cutover.
Compatibility. Confirm the PHP constraint first — this is a go/no-go gate, not a task. Then verify Laravel version support by actually installing in a scratch app. Expect to add symfony/property-access, symfony/translation-contracts, and a PSR-6 adapter (symfony/cache bridging to Laravel's store is the shortest route). Check that the engine's translation contract resolves against Laravel's translator, or accept English-only templates initially.
Sequencing.
dtmpl-laravel package — service provider, config for widget/filter/loader registration, cache bridge, error handling policy, artisan command to lint templates.Maintenance. Ownership sits with us regardless of upstream health. Expect to carry a PHP-version compatibility patch, the Laravel adapter, and the widget library as first-party code. That is a permanent, if modest, tax — and it should be scoped before commitment, not discovered later. Vendor risk is elevated: zero dependents means no one else is finding the bugs for us.
Support. Two audiences, two support surfaces. Engineers own the seams, caching, and error policy; designers own the syntax and the widget catalogue. The latter needs written documentation the package may not provide at the depth a non-technical author requires — budget for authoring a syntax reference, a widget catalogue with examples, and an error-message guide.
Scaling. Rendering is CPU-bound PHP with no obvious runtime concerns at typical CMS volumes. The scaling risks are operational rather than load-related: template compilation caching (PSR-6, invalidation on deploy and on content change), and the cost of a large widget library where a single inefficient widget call inside a loop multiplies. Watch for per-request compilation if the cache bridge is misconfigured — that shows up as latency, not errors.
Failure modes.
Ramp-up. Engineers: low — a day to wire the adapter and seams, more for the widget library. Designers: low-to-moderate — the syntax is intentionally small and reads clearly, but it is a new language with no community knowledge base, so ramp-up depends entirely on documentation we produce. Plan for a half-day workshop plus a reference document; expect the first week of authored templates to generate most of the syntax questions.
Recommendation. Treat DTMPL as a conditional pilot, not an adoption. The PHP 8.5 requirement, zero dependents, and the absent Laravel integration make the total cost of ownership — adapter, widget library, documentation, vendor-risk hedge — materially higher than the README implies. Worth a two-week spike only if the driver is a hard requirement to keep PHP out of designer-authored templates; otherwise the opportunity score of 37.89 and the dependency picture argue for staying with the incumbent path.
How can I help you explore Laravel packages today?