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 Js Laravel Package

forknetwork/twig-js

Brings Twig.js to Laravel so you can render Twig templates in the browser and share the same template syntax across PHP and JavaScript. Integrates Twig.js assets with your Laravel app for consistent, client-side templating.

View on GitHub
Deep Wiki
Context7

Getting Started

Correct the record first. The previous assessment treated this as a fork of twig.js (JavaScript). The v4.0.0 release notes — "Refactored all Twig namespaces to use the 2.7+ standard… Removed some old deprecated Twig class references… in preparation of release of 3.0" — are unmistakably PHP Twig terminology (Twig\ namespaces, Twig_* → Twig\* migration, upstream Twig 3.0). Treat this as a PHP Twig integration for Laravel, installed via Composer.

Verify the actual Composer package name in composer.json (the -js suffix in earlier notes may be wrong), then:

composer require forknetwork/twig   # confirm real composer name first

Auto-discovery usually handles the service provider; otherwise register it in config/app.php, then publish any config:

php artisan vendor:publish --tag=twig

First render. Create resources/views/hello.twig:

Hello {{ name }}!

Render from a route or controller:

Route::get('/', fn () => view('hello', ['name' => 'World']));

Where to look first, in order:

  1. composer.json — package name, extra.laravel (auto-discovery, providers, aliases), and the twig/twig version constraint. That pin dictates which Twig syntax you actually get.
  2. The service provider — how the Twig Environment is constructed, which loader is used, and how the view engine is bound.
  3. config/twig.php (if published) — autoescape, cache path, namespaces, extensions.
  4. Upstream Twig docs (twig.symfony.com) — the bridge is thin, so behavior mostly mirrors Twig itself.

First real use case: rendering .twig templates inside Laravel when the same templates must also render outside Laravel (Symfony, legacy PHP, or a static build). That is where a Twig bridge earns its keep over Blade.

Implementation Patterns

Standard view rendering. The bridge registers a view engine, so view() and View::make() just work. Use view composers exactly as you would for Blade:

View::composer('emails.*', fn ($view) => $view->with('brand', config('app.name')));

Wrapping Laravel helpers as Twig functions/filters. The bridge ships nothing Blade-specific; register what you need:

$twig->addFunction(new \Twig\TwigFunction('route', fn ($n, $p = []) => route($n, $p)));
$twig->addFilter(new \Twig\TwigFilter('asset', fn ($p) => asset($p)));
$twig->addFunction(new \Twig\TwigFunction('csrf_token', fn () => csrf_token()));

Register these in a dedicated service provider (or in config/twig.php under extensions) rather than ad-hoc per request.

Shared syntax with non-Laravel Twig. Keep templates to the intersection both runtimes support. Anything registered here (route, asset, csrf_token) will fail at the other consumer unless mirrored. Pin both to the same Twig line so syntax features match.

Caching. In production, point cache at storage/framework/views/twig (or similar). In dev, disable ('cache' => false) so you don't chase stale renders. If the cache directory isn't writable, Twig silently compiles every request — slow, but not always loud.

Per-environment options. Build the environment with autoescape from config, not per template, so behavior is predictable:

new \Twig\Environment($loader, [
    'cache' => app()->isProduction() ? storage_path('framework/views/twig') : false,
    'autoescape' => 'html',
]);

Testing. Because extensions are process-global, reset between tests (or spin up a fresh Environment per case). Otherwise a filter registered in one test leaks into another.

Gotchas and Tips

v4.0.0 is a breaking release. "Removed some old deprecated Twig class references" means anything extending or referencing Twig_Environment, Twig_Extension, Twig_SimpleFilter, Twig_Filter, etc. will break. Migrate to Twig\Environment, Twig\Extension\AbstractExtension, Twig\TwigFilter, Twig\TwigFunction before bumping. Grep your app and custom extensions for Twig_.

Another major is coming. The notes say this is "in preparation of release of 3.0" — a follow-up release aligning with upstream Twig 3.0 is planned. That likely removes the deprecated APIs entirely. Don't pin ^4.0 and forget it; budget a second migration pass.

Version-number confusion. Package version is 4.0.0, but the notes reference Twig 3.0 (upstream). Confirm whether a v5 tracks upstream Twig 3.0, and whether v4 is the last Twig-2.x line. Read the CHANGELOG/UPGRADE notes, not just the release title.

Autoescape parity with Blade. Blade escapes {{ }} as HTML by default; Twig's default depends on the configured autoescape option, which bridges frequently set to false. That means {{ user.bio }} can render raw and reintroduce XSS after a Blade migration. Set autoescape: 'html' explicitly and verify per environment.

No Blade directives. @csrf, @auth, @component, @include do not exist. You must either port them as Twig tags/extensions or rewrite templates in Twig syntax ({% include %}, a custom {% csrf %} tag). Budget for this if you're porting a Blade app.

Extension registration is global. A filter registered once is available to every template in the process — including queue workers and tests, and, in multi-tenant setups, across tenants. Scope by building a fresh Environment per tenant, or accept the global behavior knowingly.

Error line numbers are Twig's, not your file's. With {% extends %} and {% include %}, stack traces point at the compiled template. Render the offending template in isolation and log the context array to find the actual bug.

Cache invalidation. Twig does not auto-detect template changes when cache is enabled. In dev, keep it off or you'll be debugging a stale render.

Version pinning. With a major bump shipped and a second on the horizon, pin exact versions ("forknetwork/twig": "4.0.0") and run composer audit before deploying.

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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo