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

Reactjs Php Bundle Laravel Package

qpautrat/reactjs-php-bundle

A Symfony bundle that integrates React.js into your PHP application, letting you render React components server-side and manage their assets from Twig templates with minimal setup and no separate JavaScript build pipeline.

View on GitHub
Deep Wiki
Context7

Getting Started

Confirm the dependency before anything else. This bundle is a thin Symfony wrapper around reactjs/react-php-v8js, which executes JavaScript through the V8Js PHP extension. No extension, no package.

php -r 'var_dump(extension_loaded("v8js"));'

If that prints false, stop and solve ops first — either pecl install v8js (needs libv8 headers, painful on some distros) or, far easier, build on a Docker image that ships the extension. This one requirement eliminates most shared hosting.

Install and register:

composer require qpautrat/reactjs-php-bundle
// AppKernel.php (Symfony 2/3 era)
new Qpautrat\ReactjsPhpBundle\QpautratReactjsPhpBundle(),
# config.yml — typical shape; confirm exact keys in the README
qpautrat_reactjs_php:
    react_path: "%kernel.root_dir%/../node_modules/react/dist/react.js"
    components_path: "%kernel.root_dir%/../web/js/components.js"

Where to look first: the bundle is small. Find the renderer service and the Twig extension (bin/console debug:container | grep -i react), then read ReactJS.php from the underlying library — setComponent() + getMarkup() is the entire API you're configuring.

First use case: server-render one presentational component (a product card, a comment, a price block) into a Twig template so crawlers and first paint get real markup without standing up a Node SSR service.

{{ react_component('ProductCard', { title: product.title, price: product.price }) }}

If you're in Laravel: don't fight the bundle. composer require reactjs/react-php-v8js, bind ReactJS as a singleton in a service provider, and expose a Blade directive. You lose the config sugar and gain a working integration.

Implementation Patterns

Precompile everything. The bundle just evals your components_path file inside V8. JSX is not transpiled at runtime. Use webpack/Babel to emit one bundle where each component is assigned to a global the library can reach (window.ProductCard = ...) — not a module export graph.

Controller → props → renderer. Build props as a plain PHP array, hand it to the renderer, echo the markup. Keep it as a dedicated renderer service of your own:

class ReactRenderer
{
    public function __construct(private ReactJS $react) {}

    public function render(string $component, array $props = []): string
    {
        try {
            $this->react->setComponent($component, $props);
            return $this->react->getMarkup();
        } catch (\Throwable $e) {
            $this->logger->error('SSR failed', ['component' => $component, 'e' => $e]);
            return ''; // container falls back to client render
        }
    }
}

Hydrate, don't re-render. Emit the server markup into a div with an id, embed the same props as JSON, and call ReactDOM.hydrate(<Component {...props} />, el) on the client. Server and client must agree byte-for-byte or React throws away the markup.

<div id="product-{{ product.id }}">{{ react_component('ProductCard', props) }}</div>
<script>hydrate('product-{{ product.id }}', {{ props|json_encode|raw }});</script>

Cache aggressively. Booting V8 and evaluating React per request is expensive. Wrap the renderer in a cache keyed by component + md5(json_encode($props)). For mostly-static components this turns SSR into a cache hit.

Wrap, don't scatter. Inject your ReactRenderer into controllers/services rather than calling the bundle's Twig function everywhere. It gives you one place for logging, fallback, and caching, and makes the Twig helper just sugar.

Gotchas and Tips

Version lock-in is the big one. react-php-v8js targets an old React (React.renderComponentToString, pre-16). Modern React moved to ReactDOMServer.renderToString. Verify which React build your react_path points at and patch the JS bootstrap if needed — many "it returns empty string" reports are just a mismatched server build.

Never interpolate user data into JS source. Only pass props through json_encode/the PHP array API. Anything that lands in the evaluated string is a code-execution vector inside your PHP process.

Props must be JSON-serializable. No closures, resources, or circular references. Dates become strings; be explicit.

Hydration mismatches come from anything non-deterministic during SSR: Date.now(), Math.random(), window/localStorage access at render time. Guard browser-only code in componentDidMount/useEffect, not render.

Watch memory and time limits. V8 contexts are heavy; add V8Js::setTimeLimit() and a sane memory_limit. Log V8 exceptions — they surface as opaque PHP errors otherwise.

Symfony compatibility. The bundle predates Flex and Symfony 5+. On modern Symfony (or Laravel), use reactjs/react-php-v8js directly; the bundle saves you maybe 20 lines of config.

Debugging checklist: call getMarkup() in a bare controller before wiring Twig; confirm the component is actually a global after your bundle loads ($react context, V8Js::executeString('typeof ProductCard')); check that components_path isn't a webpack module chunk with require calls it can't resolve.

Extension points: replace the renderer service with your own implementation (caching, fallback, multi-component batching) and decorate the Twig extension. This is the intended way to add behavior — the bundle itself has very little code to fork.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource