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

Financial Twig Extension Bundle Laravel Package

hostnet/financial-twig-extension-bundle

Hostnet Financial Twig Extension Bundle adds Twig filters and functions for financial calculations and formatting, helping Symfony templates handle values like VAT, interest, and currency display without extra PHP logic. Simple to install and integrate.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit: framework-seam mismatch, portable core. The package is a Symfony Bundle — it ships a Bundle subclass, a DI Extension, services.yaml resource loading, and Twig extensions registered via the twig.extension tag. Laravel has no bundle lifecycle, no DI compiler passes, and no service tagging; the container will autowire plain classes but will silently ignore the bundle's wiring. The genuinely reusable asset is the Twig extension layer itself: Twig\Extension\AbstractExtension implementations with filters/functions are framework-agnostic and will run anywhere Twig runs. That is the part worth evaluating; the Symfony scaffolding is disposable. There is a second seam beyond Symfony→Laravel: Laravel ships Blade, not Twig, so the filters have no natural consumer unless we introduce Twig.

Integration feasibility: possible, but effort-to-payoff is poor on the default stack. Three viable routes, in descending order of pragmatism: (a) port the filter bodies into a Laravel FinancialFormatter service plus Blade directives (@money, @percent) — likely 150–300 LOC, no new runtime dependency; (b) introduce rcrowe/twigbridge in a bounded rendering context (PDF statements, financial email templates) and register each extension manually in a service provider's boot(); (c) fork, strip the Bundle namespace, republish internally as a Laravel package. Pulling symfony/dependency-injection + framework-bundle into a Laravel app to obtain a handful of formatting filters is a weight and upgrade-coupling cost I would not sign off on.

Technical risk: maturity and supply chain, not code complexity.

  • Adoption signal is weak: 1 star, 0 dependents, composite score 0.125, opportunity 31.72. Zero dependents means effectively zero external battle-testing and no downstream canary for breakage.
  • Upstream is a single agency org (Hostnet, a real Dutch firm, so accountability exists) rather than an individual; MIT license removes legal friction.
  • The release date (2025-02-11) suggests recent attention, which is the one positive maturity datapoint.
  • The bundle's CI matrix targets Symfony/PHP, not Laravel. Any behavioral guarantee on our stack is ours to write.
  • Financial display semantics are consequential: rounding mode (half-up vs. banker's), negative representation (-1,234.00 vs. (1,234.00)), and grouping separators are audit-visible. We cannot inherit correctness here; we must characterize it.

Key questions to resolve in a one-day spike:

  1. What exactly does it expose — currency symbols, money formatting, percentages, sign display, abbreviation (K/M/B)? Is the surface 2 filters or 20?
  2. Does it depend on moneyphp/money, brick/money, or just number_format/NumberFormatter? A dependency on a money value object changes the port significantly.
  3. Are extension classes constructor-injected with Symfony services or config objects (locale provider, formatter config)? That determines whether they instantiate standalone.
  4. Is ext-intl / ICU a hard requirement?
  5. How does its output compare against Laravel's native Number::currency() and whatever money library we already run?
  6. Test coverage and PHP/Twig/Symfony version constraints — will it even install cleanly alongside Laravel 10–12 on PHP 8.2–8.4?

Integration Approach

Stack fit: conditional. If the application is Blade-first, only the formatting logic transfers and the Symfony packaging is pure overhead. If we already render Twig somewhere — most commonly PDF invoices (dompdf/snappy) or transactional financial email — the extensions drop in with a manual registration loop and the bundle is genuinely useful. Determine this first; it bifurcates the whole plan.

Migration path.

  • Lane A (default recommendation): port. Read the extension classes, extract filter bodies into App\Support\Formatting\FinancialFormatter, expose via Blade directives and a facade. Cost: ~200 LOC plus tests. Removes the dependency entirely; no TwigBridge, no Symfony DI, no upstream risk. Downside: we own divergence from upstream forever, which for a frozen formatting ruleset is acceptable.
  • Lane B: bridge. Add rcrowe/twigbridge scoped to one rendering context, then in a service provider boot(): resolve the Twig environment and call addExtension() for each extension class. This replicates Symfony's tag semantics by hand. Cost: 5–8 engineering days including TwigBridge bake-in and CI, plus ongoing TwigBridge/Laravel major-version skew risk.
  • Lane C: fork. Viable precisely because the package is small — strip the Bundle class and DependencyInjection/, keep the extension classes, publish under our vendor namespace. Reasonable if we expect to add filters (e.g., FX conversion, compact notation) and want upstream's structure as a starting point.

Compatibility. Verify Twig 3.x compatibility (Twig 1/2 APIs are removed in modern Laravel-adjacent stacks), PHP constraint overlap with our runtime, and — for Lane B — that TwigBridge supports our current Laravel major before committing. TwigBridge historically lags Laravel releases by a quarter or more; that lag becomes our upgrade blocker.

Sequencing.

  1. Source inventory: enumerate filters, dependencies, and constructor signatures (0.5 day).
  2. Decide lane based on whether Twig already exists in the stack.
  3. Write characterization tests against the original before any modification — golden fixtures covering locales (en_US, en_GB, de_DE, ja_JP), negatives, zero, large values, and rounding boundaries.
  4. Implement the chosen path.
  5. Diff outputs against the golden fixtures; any delta is a deliberate, documented decision (especially rounding and negative formatting).
  6. Ship behind a feature flag on one low-traffic surface (internal admin report), then expand.
  7. If Lane A/C: remove the Symfony dependency and record the divergence in an ADR.

Operational Impact

Maintenance. We own this regardless of lane. Lane B leaves us coupled to two upstream cadences (Hostnet's Symfony releases and TwigBridge's Laravel support) for a small amount of logic — a poor maintenance ratio. Lane A/C reduces upstream surface to zero at the cost of owning ~200 lines we can fully test. Given 0 dependents and 1 star, assume no one else will file the bug we hit.

Support. No commercial support; GitHub issues only, with a low-activity repo suggesting slow response. Name an internal DRI. Keep the fork-ready diff current — it is small enough that re-vendoring on an upstream CVE or ICU behavior change is a hours-scale task, not a project.

Scaling. Runtime cost is negligible: formatting is CPU-bound, no I/O, sub-microsecond per call. Two real considerations: (i) do not instantiate NumberFormatter per cell — memoize a formatter service per locale, or a 10k-row financial table becomes a 10k-allocation render; (ii) if rendering is server-side in request path, keep formatter construction out of the loop and out of the container resolve path.

Failure modes.

  • Missing ext-intl / incomplete ICU data in a container image → exception or wrong separators at render time, not boot time. Pin the extension in composer.json and assert it in a health check.
  • Silent non-registration (Lane B) — the Symfony DI config is ignored, filters never attach, and Twig throws Unknown "money" filter on first render of a production page. This is the highest-probability failure and it is a runtime, not startup, failure; add a boot-time smoke assertion that each filter name resolves.
  • Rounding/negative convention drift — accounting expects ($1,234.00); a formatter emitting -$1,234.00 is a visible, audit-relevant defect. Lock with golden tests.
  • Locale mismatch between app locale and formatter locale → wrong currency symbol on multi-region statements.
  • TwigBridge version skew breaking extension registration on the next Laravel upgrade (Lane B only).

Ramp-up. Low. An engineer can read the entire filter implementation in under an hour. Budget 1 day for the source-inventory spike, 2–4 days for Lane A implementation plus characterization tests, 5–8 days for Lane B including TwigBridge adoption and CI. Team learning cost is near zero for Lane A (Blade directives are familiar); moderate for Lane B, where engineers must understand Twig extension registration and Symfony service-tag semantics transposed into a Laravel provider.

Verdict. Adopt the logic, not the bundle. The package is small, MIT-licensed, and recently released, but its 1-star / 0-dependent profile means the adoption signal we would normally rely on does not exist, and its Symfony packaging is dead weight in a Laravel application. Port the filters behind a tested internal formatter service unless Twig already exists in the stack, in which case bridge it in one bounded rendering context only.

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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels