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

Twig Instanceof Laravel Package

lelyfoto/twig-instanceof

Twig extension that adds an instanceof test, letting templates check whether a value is an instance of a given class or interface. Lightweight and easy to register for cleaner, type-aware Twig conditionals.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit — conditional, and the condition is usually not met. This is a Twig extension, not a Laravel package. v1.3 does not change that. Laravel's view layer is Blade; Twig only appears in a Laravel codebase through a third-party bridge (rcrowe/twigbridge being the common one) or as legacy code from a Symfony/Craft/Slim/Drupal origin. If the target application is Blade-first, the entire value proposition collapses: Blade compiles to PHP, so @if ($model instanceof \App\Models\User) already works with zero dependencies. Adopt Twig and this package only if Twig is already a fixed constraint. The release notes reinforce which ecosystem this package actually serves — both merged PRs are Symfony-track, not Laravel-track.

Even inside a Twig app, the design is questionable. instanceof in a template moves type dispatch out of PHP and into the view layer. Templates become coupled to fully-qualified class names that no static analysis, IDE, or refactor tool will track; a namespace rename produces a silent false rather than an error. Preferred patterns are a view model/DTO exposing a boolean ($view->isUser), a domain-level discriminator string, or a purpose-named Twig test (is_admin_user). This package exposes the raw mechanism instead of the domain concept. Nothing in v1.3 addresses this.

Integration feasibility — mechanically trivial, strategically thin. The surface area is one extension class plus one expression node. Registration is a single line in config/twigbridge.php's extensions array, or a service provider resolving the Twig environment and calling addExtension(). No service provider, config file, facade, migration, or framework coupling is shipped — good for portability, but it means there is still zero integration guidance and no Laravel-idiomatic entry point to inherit. v1.3 added no docs, no examples, and no Laravel-specific surface.

Technical risk — unchanged in kind, modestly improved in maintenance signal.

  • Twig version drift (high, slightly softened). Extensions that subclass Twig\Node\Node / Twig\Node\Expression\AbstractExpression remain the most brittle kind; Twig has repeatedly changed compile() signatures and internals across 3.x minors, and Twig 4 will break node-level extensions outright. The "Add a return type to Fix deprecated message" PR is a genuine positive signal: it indicates the node code is being touched to track upstream deprecations rather than left to rot, and it implies the codebase is on modern PHP (return-type declarations imply PHP 8.x targeting). But a single deprecation fix is not a compatibility matrix, and there is still no evidence of Twig 4 readiness or a CI matrix. The legacy Twig_Extension question from the prior assessment is now more likely to resolve favourably, since Symfony 8 implies Twig\Extension\AbstractExtension — confirm in the spike rather than assume.
  • Supply chain / bus factor (high, marginally improved). 8 stars, 0 dependents, one author, MIT. v1.3 adds two first-time contributors (@ceponcet, @jonmldr). That is a real but weak signal: drive-by PRs from the Symfony upgrade cycle, not co-maintainership. There is still no community scrutiny, no security review signal, and no downstream usage to catch regressions. Treat the code as a sample to vendor, not a dependency to trust. The contributor uptick does not change that posture.
  • Sandbox and information disclosure (medium). Expression-node extensions sit below Twig\Sandbox\SecurityPolicy; if this registers as a raw node rather than a named test, it may bypass the allowed-tests allowlist. String-driven class resolution can also invoke the autoloader and surface class names in exception messages rendered to users. v1.3 does not address this, and the release notes give no indication the maintainer considers it.
  • Semantic edge cases (low/medium). null handling, interface and parent-class matching, and proxy objects (Doctrine proxies, lazy ghosts) where instanceof against the base class succeeds but against a sibling subclass does not. Still undocumented in the release notes; still to be discovered in the spike.

Key questions for the maintainer spike (revised for v1.3)

  1. Syntax: {% if x is instanceof('App\\Models\\User') %} or operator form? Class-string only, or does it accept a constant()/::class-equivalent?
  2. Does it delegate to native PHP instanceof semantics (interfaces and parents yes, null no error)?
  3. Declared compatibility matrix: which Twig versions does the new Symfony 8 constraint actually admit? Does the widened Symfony constraint widen or merely intersect the Twig constraint twigbridge pins?
  4. Does the return-type fix (PR #3) change the public signature in a way that breaks subclasses or the compile path? Read the diff, not the changelog line.
  5. Is it registered as a Twig test (allowlistable via SecurityPolicy::setAllowedTests) or as a bare expression node?
  6. Does the repo ship tests and CI covering both the compile path and the cached-template path — and did v1.3 add or regress any coverage?
  7. Is the class string resolved at compile time or lazily per render (autoloader hot path)?

Integration Approach

Stack fit. Direct and correct for standalone Twig, Symfony, Slim, Craft CMS, Drupal, Bolt. v1.3 extends the Symfony reach to Symfony 8, which is the strongest argument yet that this is a Symfony-ecosystem artifact. For Laravel: still only viable via rcrowe/twigbridge or an equivalent bridge, with manual registration. For a Blade-based Laravel app the recommendation remains a firm no — do not introduce Twig to obtain an operator Blade already has natively.

Migration path. Unchanged. Existing Twig-on-Laravel: add the extension class to the extensions array in config/twigbridge.php, run php artisan config:clear, then php artisan view:clear (twigbridge caches compiled templates under storage/framework/views; a stale compiled template will not pick up the new node). Smoke-test one template that renders both branches of the conditional. No schema, data, or route migration; no downtime. If upgrading v1.2 → v1.3 in place, treat it as a no-op deploy but re-run the view-cache clear anyway, since the return-type change touches the compiled path.

Recommended alternative path. Unchanged and still preferred: implement an internal InstanceOfTest extends TwigTest in application code — roughly 25 lines — register it locally, and add one PHPUnit feature test asserting both the true and false branches. This removes the third-party dependency, keeps the sandbox allowlist explicit and auditable, and lets you add domain-named tests alongside it so templates stop referencing FQCNs. Second-best: vendor or fork the package into a private namespace so a Twig upgrade cannot strand you. v1.3 does not move the needle enough to promote "take the dependency" above either option.

Compatibility. Run composer why twig/twig to see the constraint twigbridge already pins; confirm the extension's v1.3 constraints intersect rather than widen it. The Symfony 8 PR may have loosened symfony/* to ^8.0 while leaving Twig unchanged — verify independently, since Symfony version and Twig version are not the same axis. Confirm the class namespace (Twig\Extension\AbstractExtension vs the legacy Twig_Extension); v1.3 makes Twig 3 support near-certain but still not formally stated. Pin Twig and the extension to exact versions in composer.json.

Sequencing

  1. Spike (0.5 day) — branch install of v1.3 specifically, render a template exercising the expression, confirm parse, compile, and cache-invalidation behavior. Diff v1.2…v1.3 while you are in there.
  2. Security review (0.5 day) — sandbox policy interaction, exception message leakage, autoloader behavior on undefined classes.
  3. Decision gate — adopt as-is / vendor-fork / build the internal test. Default remains the internal test.
  4. Harden if adopted — pin versions, add a CI render test that fails the build on a Twig or Symfony bump, name an owner.
  5. Roll out — template cache clear only; no user-facing migration.

Operational Impact

Maintenance. Near-zero runtime maintenance, disproportionate governance overhead for the value delivered. The package has no framework-facing config surface, so Laravel upgrades cannot break it — a genuine plus that v1.3 preserves. The risk remains entirely on the Twig side, and the v1.3 return-type fix is the first hard evidence that someone is watching that side. That lowers the probability of silent decay without eliminating it. The fork burden still lands on you the moment Twig ships a breaking minor. Vendoring converts an unbounded dependency risk into a bounded, readable ~100-line internal asset.

Support. No vendor, no SLA, GitHub issues as the only channel, one maintainer plus two one-time contributors. v1.3 improves the optics of support — two merged external PRs in one release is the healthiest signal this repo has produced — but not the substance: neither contributor has commit rights or a track record, and neither PR was a security or correctness fix. Internal documentation and a named owner remain mandatory even for a trivial adoption. Budget the "one engineer reads the whole file" cost explicitly rather than assuming it is free.

Scaling. Negligible and unchanged. instanceof is an opcode-level O(1) check. Two caveats: class-string resolution at render time can touch the Composer classmap/autoloader on first use per process (warm it, or the cost is trivial anyway); and compiled Twig templates are plain PHP, so OPcache applies normally. There is no per-render allocation or memory concern at any realistic template volume. The real scaling limit is template readability and reviewability, not this operator.

Failure modes

  • Twig upgrade → compile-time fatal on every page including the affected template. Blast radius equals template reach. Mitigate with a pinned Twig and a CI render test. v1.3 does not add that CI test, so the mitigation remains yours.
  • Symfony constraint widening → resolve-time surprise. The Symfony 8 PR may alter the dependency graph in ways that only surface on the next composer update. Lock-file review before adopting v1.3.
  • Class renamed or re-namespaced → silent false. The conditional quietly falls to the else branch. This is the most dangerous mode: no error, data-dependent, near-invisible in code review. v1.3 does not touch it. This alone justifies moving to domain-named booleans or tests.
  • Sandbox misconfiguration → either hard failure in sandboxed templates or a policy bypass worth a security finding.
  • Exception leakage → autoload failure on an undefined class string can surface class names in a rendered error path.
  • Proxy semantics → Doctrine/Eloquent proxies match the base class but not sibling subclasses; document the expected behaviour or reviewers will misread the intent.

Ramp-up. About an hour for a developer already fluent in Twig's compile/cache model; roughly half a day for a Blade-only team, who must first internalize that Twig compiles and caches to disk. Reviewer ramp-up still exceeds author ramp-up: every FQCN in a template is an untracked coupling that a reviewer must mentally diff against the PHP model layer on every change. Nothing in v1.3 reduces that.

Overall recommendation (revised for v1.3). Conditional no-go for a Blade-based Laravel application — unchanged, and the release notes make the mismatch clearer by confirming the package's centre of gravity is Symfony. Conditional go only where Twig is already fixed: prefer an internal ~25-line Twig test or a vendored fork over the Composer dependency. If the dependency is taken, take v1.3 over v1.2 (the return-type fix and Symfony 8 support are strictly improvements), pin it exactly, review the composer lock diff, and gate it behind a CI compatibility test covering both Twig and Symfony bumps. The release upgrades the package from "sample to vendor" to "sample worth watching"; it does not upgrade it to "dependency to trust."

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.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk