smnandre/twigmetrics
TwigMetrics is a lightweight Twig extension for adding metrics to your templates. It provides simple helpers to collect, expose, and render runtime statistics, making it easy to instrument views and surface useful data with minimal configuration.
TwigMetrics is a Twig template analyzer, not a Blade one — the first decision is whether it applies to your project at all. If you're on Laravel with Blade, it won't see your views; if you're on Symfony, a Twig bridge (e.g. rcrowe/twigbridge), or a standalone Twig templating layer, it's directly useful.
composer require --dev smnandre/twigmetrics
vendor/bin/ and the README's "Usage" section — that is where the CLI flags, the target-path argument, and the report/output options live. Read the config file section before running anything, because metric thresholds and excluded paths are set there, not on the command line.vendor/bin/twigmetrics templates/
base.html.twig with nine nested {% if %} blocks that everyone is afraid to edit.Baseline-then-ratchet in CI. Commit the machine-readable report (JSON, if available) to the repo, then in CI regenerate it and diff against the committed copy. Fail the build only when a new template exceeds thresholds or the aggregate score regresses. This avoids the classic "adopt the tool, fail 400 times on day one, disable the tool on day two" outcome.
Scope by directory, not by repo. Run separate invocations for templates/components/, templates/email/, and templates/admin/. A 40-line limit is reasonable for a button component and absurd for a page layout; per-scope runs let you set honest thresholds instead of one compromised global number.
Pre-refactor survey. Before a template-cleanup sprint, run the analyzer and turn the top-N list into tickets. Re-run afterwards and attach the before/after chart to the PR description — v1.1.0's charts make this a genuinely cheap thing to do, and it's the single highest-leverage habit with this tool.
Pair with existing linters. TwigMetrics measures shape and complexity; it does not catch undefined variables or syntax errors. Run it after twig:lint and any Twig-flavoured static analysis, so you're never analyzing templates that don't compile.
Composer script alias. Wrap the invocation in a composer metrics script alongside composer test and composer cs. Tools that need a remembered one-liner get forgotten; tools on a script name get run.
CI artifact publishing. Emit the chart HTML as a build artifact on every PR. Reviewers get a link instead of a number in a log, which materially increases the chance anyone reads it.
v1.1.0 invalidates your old numbers. The release reworks dimension metrics. Any baseline, threshold, or historical chart produced under v1.0.x is not comparable to v1.1.0 output — regenerate and re-commit the baseline in the same PR that bumps the version. If you have a ratchet gate, this is the one upgrade step that will silently break it: the score will "regress" purely from the rework. Pin the version in CI until you've done this deliberately.
Charts may be an optional path, not a default. Rendering charts usually pulls in extra output code (and possibly assets). Confirm whether the chart output requires a flag, an extra package, or a specific report format before assuming a plain run produces HTML — and check whether the generated file references assets over CDN, which will be blank in an offline CI artifact or behind a strict CSP.
Exclude generated and vendored templates. Compiled caches, vendor/ templates, and machine-generated scaffolds (form themes, CRUD boilerplate) will dominate the report and drown out the templates you actually maintain. Set exclusions in config, not by narrowing the target path — otherwise they creep back in.
Metrics are heuristics, not verdicts. Complexity scores reward splitting; splitting rewards scores. A template pulled apart into eleven single-use includes can score beautifully and be worse to read. Treat the ranked list as a reading order, not a to-do list, and never refactor a template purely because a number moved.
Watch for formatting sensitivity. Template metric tools parse Twig structure; heavy whitespace, long inline {% set %} chains, and unusual macro patterns can shift results between versions. If a template's score jumps after a version bump with no code change, suspect the parser before you suspect the template.
Debugging a surprising score. Reduce to the smallest template that reproduces it. Dimension scores are usually aggregates of several sub-metrics, and the per-file breakdown (if the report exposes it) tells you which dimension is driving the number — that's where to look, not at the headline figure.
Extension points. If the config exposes custom metrics or dimension definitions, add them for project-specific rules (e.g. "no |raw in user-content templates") rather than trying to infer the rule from a generic score. Custom rules survive version bumps far better than threshold tweaks.
Keep the report out of the runtime. The chart HTML and JSON reports should be gitignored build output (or committed deliberately as a baseline) — never deployed. Confirm your build pipeline doesn't sweep the report directory into the artifact you ship.
How can I help you explore Laravel packages today?