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

Chrome Laravel Package

chrome-php/chrome

Chrome PHP lets you control headless Chrome or Chromium from PHP, synchronously or asynchronously. Open pages, navigate, run JavaScript, take screenshots, generate PDFs, and emulate mouse and keyboard input with a simple, IDE-friendly API. Requires PHP 7.4–8.5 and Chrome/Chromium 65+.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. chrome-php/chrome is a framework-agnostic PHP client that drives a real Chrome/Chromium binary over the DevTools Protocol, communicating with the browser process via a WebSocket. That means the package is not a rendering library — it is a process orchestrator plus protocol client. In a Laravel application it occupies the same architectural slot as a headless-browser microservice would, except the browser runs as a child process on the same host as the PHP worker. For teams already running PHP workers, this removes a network hop and a service to deploy; for teams running ephemeral, autoscaled containers, it adds a heavyweight native dependency (a ~300 MB browser binary) to every runtime image that needs rendering. The synchronous-looking API (getReturnValue(), waitForNavigation()) is actually promise-based under the hood, so the "async" claim is real but only useful inside a long-running process that manages its own event loop — not inside a typical FPM request. Architecturally, this package wants to live in queue workers, not web requests.

Integration feasibility. Composer install is trivial (composer require chrome-php/chrome), and the API surface is small and IDE-friendly: BrowserFactory → Browser → Page → navigation/evaluate/screenshot/pdf. There is no Laravel service provider, config file, or facade, so integration is a thin wrapper you write yourself. The real feasibility question is environmental: the package needs CHROME_PATH or a discoverable chrome/chromium-browser binary, a writable temp dir for the generated userDataDir, and enough shared memory (/dev/shm) to avoid Chrome crashing. PHP 7.4–8.5 and Chrome 65+ are supported, but the README is explicit that only Linux is tested — macOS/Windows are "compatible," not validated. That is acceptable for server-side Laravel but a caveat for developer laptops.

Technical risk. The dominant risks are operational rather than code-level. First, blocking semantics: a synchronous navigate()->waitForNavigation() call can hold a PHP-FPM worker for 30 seconds by default; without queue isolation this is a self-inflicted availability incident. Second, external binary coupling: Chrome auto-updates, and DevTools Protocol surface changes across major versions, so a browser upgrade can break rendering in production without a Composer change. Third, security surface: this package will happily fetch internal URLs, file:// paths, and credentialed endpoints — a user-supplied URL parameter reaching this library is a server-side request forgery primitive and a potential data-exfiltration vector. Fourth, process hygiene: orphaned Chrome processes, zombie children, and accumulating temp profile directories are the classic failure signature. Fifth, maturity signal: README/CHANGELOG/releases exist and the project is actively released (most recent 2026-07-06, MIT), but the reported "Dependents: 0" means downstream adoption cannot be used as a proxy for production hardening — the 2.6k stars and the changelog are the better evidence.

Key questions.

  • What is the actual job — authenticated screenshots, PDF invoices, SPA crawling, visual regression, or end-to-end testing? The answer changes the concurrency and isolation design materially.
  • What is peak and sustained volume (pages/minute), and what is the acceptable p95 render latency?
  • Where will Chrome execute: same container as PHP, sidecar, or dedicated render fleet? Is /dev/shm sized, and is noSandbox acceptable under our container security policy?
  • Will any input URL be user-controlled? If yes, what egress allowlist and URL validator sits in front of it?
  • Which Chrome version is pinned, and who owns the upgrade-and-retest cadence when the base image moves?
  • Do we need PDF and screenshot fidelity guarantees (fonts, emoji, CJK) that require baked-in font packages?

Integration Approach

Stack fit. Good fit for a Laravel monolith that already has a queue and workers. The natural shape is a RenderPageJob dispatched to a dedicated queue, a thin BrowserManager singleton that holds a BrowserFactory with persistent options (windowSize, noSandbox, userAgent, proxyServer, customFlags), and a PageRenderer service that owns navigation, waiting, and artifact storage. Keep the package behind your own interface (HtmlRenderer, PdfRenderer, ScreenshotRenderer) so the vendor is swappable. Do not let HeadlessChromium\* classes leak into controllers or domain code.

Migration path. If the current solution is wkhtmltopdf, dompdf, or a Puppeteer/Playwright microservice, the migration is incremental and low-drama because the output contract (bytes or a file path) is identical. Sequence it as: (1) stand up a RenderPageJob on the existing queue with the package wired to a single route behind a feature flag; (2) diff outputs against the incumbent for a sample of real documents and pages; (3) move traffic by route or tenant; (4) decommission the old path only after a full billing/reporting cycle has run clean. If the incumbent is a separate Puppeteer service, be honest about the trade: you are trading a network boundary and a language boundary for a native binary inside your PHP image. That is a win on latency and operational count, a loss on blast radius and independent scaling.

Compatibility. Pin the package minor version in composer.json and pin the Chrome/Chromium version in the Docker image — never let both float. Verify PHP 8.x against the Laravel version in use and confirm the queue worker's memory limit (memory_limit) comfortably exceeds a browser session's footprint. Confirm the runtime has the fonts and shared libraries Chrome needs (libnss3, libatk, fontconfig, plus CJK/emoji font packages if document fidelity matters). If Redis/Horizon is the queue backend, set retry_after above the worst-case render timeout or jobs will be double-dispatched.

Sequencing.

  1. Spike (1–2 weeks): containerize Chrome, prove screenshot + PDF + JS evaluation on the target Laravel version, measure cold-start and per-page latency, validate the Docker sandbox flags.
  2. Wrapper + hardening: build the service interface, URL allowlist/egress policy, per-job timeouts derived from sendSyncDefaultTimeout and startupTimeout, structured logging via a PSR-3 debugLogger, and guaranteed $browser->close() in finally.
  3. Worker fleet: dedicated queue, dedicated worker pool, health check that actually launches and closes a browser.
  4. Observability: metrics for render duration, failure class (OperationTimedOut, NavigationExpired, browser crash), orphan process count, and temp-dir growth.
  5. Scale-out and cost review once volume is real.

Operational Impact

Maintenance. Two things version independently and both must be maintained deliberately: the Composer package and the Chrome binary. Budget a recurring task for browser-image refresh plus a smoke-render test in CI that fails loudly if Chrome upgrades break navigation or PDF output. The package itself is MIT and actively released, so security patches should be absorbable as routine minor bumps, but each bump deserves a changelog read — the changelog and releases are the primary support contract here.

Support. There is no commercial support and no vendor SLA; support is GitHub issues plus the README. That is normal for this class of package and is acceptable for internal tooling, less so for a customer-facing, revenue-path feature. Plan for at least one engineer to become the named owner of "browser rendering" — this is not a package you install and forget.

Scaling. Scale horizontally by adding worker processes, not by adding concurrency inside a process. The practical unit is one browser instance per worker with a small number of pages per browser, recycled after N jobs to bound memory growth. Because Chrome is CPU- and memory-heavy, the render queue should be isolated from the transactional queue so a render backlog cannot starve order processing — this is the single most important scaling decision. Persistent-browser mode (keepAlive plus BrowserFactory::connectToBrowser with a socket URI file) is available and can amortize startup cost substantially, but it introduces shared-state and stale-socket handling that must be designed for, not bolted on.

Failure modes to instrument explicitly.

  • OperationTimedOut / NavigationExpired — slow or redirected pages; needs per-job timeout budgets and graceful job failure, not worker death.
  • Browser startup failure — bad binary path, missing shared libs, /dev/shm exhaustion, sandbox violations; distinguish "never started" from "crashed mid-render."
  • Orphaned Chrome processes and unbounded temp profile directories — the slow-burn outage; needs a reaper and disk alerting.
  • Memory exhaustion in the PHP worker — a rendered page with heavy assets can exhaust memory_limit even though Chrome does the work.
  • Blocked or degraded rendering by anti-bot defenses — expect a nonzero, drifting failure rate on third-party sites and treat user-agent/proxy/header configuration as a maintained surface, not a constant.
  • Security: an unvalidated URL reaching navigate() is the highest-severity failure mode in this list; enforce an allowlist and network egress policy before the first production job.

Ramp-up. Expect roughly one to two engineer-weeks for a competent Laravel developer to reach a hardened first version: a day on the API and options, a day or two on the container and Chrome dependencies, the rest on the wrapper, timeouts, observability, and failure handling. The package's learning curve is genuinely low; the operational learning curve — Chrome in containers, process lifecycle, and queue isolation — is where the time actually goes. Plan the onboarding around the operational model, not the API.

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.
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr
laravel2580/idehelpers
delatbabel/viewpages
anavel/gettext
muhamadrezaar/highcharts
delatbabel/keylists
frankkessler/salesforce-laravel-oauth2-rest
anavel/foundation
wdmtech/enviricons
eii/laravel-captcha
muka/shape-reader
tdt/json