# phpv8/v8js: Embedding Google V8 in PHP

> phpv8/v8js is a PHP 8 extension that embeds Google's V8 JavaScript engine. It suits PHP applications that need direct JavaScript execution with time and memory limits, provided the deployment can maintain its native V8 dependency.

**phpv8/v8js** — V8 Javascript Engine for PHP — This PHP extension embeds the Google V8 Javascript Engine

- Repository: https://github.com/phpv8/v8js
- Website: http://pecl.php.net/package/v8js
- Stars: 1,854 · Forks: 205
- Language: C++
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/phpv8-v8js

## Why phpv8/v8js Exists

phpv8/v8js addresses the case where a PHP application must evaluate JavaScript without moving execution to a separate browser or service. The README describes the extension as a way to execute JavaScript from PHP in a secure sandbox. Its likely users are PHP developers who need to run scripts originating in an application workflow or received from users while retaining direct access to PHP values and callbacks.

The project is not a JavaScript package manager, browser, or general Node.js compatibility layer. It is a native PHP extension that embeds Google's V8 engine. Each `V8Js` object has its own V8 context. A constructor can seed that context with PHP variables, and the PHP API can compile, execute, inspect exceptions, and configure resource limits.

The security language needs a careful boundary. The README says execution can be restricted through a time limit, a memory limit, or both. Those controls can contain runaway computation or memory consumption. The README does not document a policy for host file access, network access, subprocess creation, or other operating-system permissions. It also does not present the limits as a substitute for validating or reducing the privileges of the PHP process.

That makes phpv8/v8js most credible when JavaScript is a controlled feature inside an existing PHP service, not when it is an open execution service with unaccounted host capabilities. The extension also uses thread locking according to the README, allowing its embedded implementation to work with PHP built with ZTS enabled.

## How phpv8/v8js Moves Data Between PHP and V8

The constructor accepts an object name, an array of variables, and an optional snapshot blob. Repository header files such as `php_v8js.h` identify V8 as the core engine type exposed to the extension, while API files handle PHP method registration and object conversion. Based on that layout, the extension acts as a bridge that owns V8 contexts and converts values crossing the PHP and JavaScript boundary.

For direct execution, `executeString()` compiles and runs a script in the current context. Its parameters include a script identifier, flags, a time limit in milliseconds, and a memory limit in bytes. The method returns `mixed`. This is the simplest route when PHP already has complete JavaScript source and needs the resulting value immediately.

The API also separates compilation from execution. `compileString()` returns a script resource, and `executeScript()` accepts that resource. The documentation does not provide a complete caching policy or examples of storing compiled resources across requests, so it would be unsafe to assume that a compiled script can be persisted or reused under conditions not covered by the README.

Module handling uses PHP callables. `setModuleLoader()` registers a loader that receives a normalized module path and returns JavaScript code. `setModuleNormaliser()` can intercept path resolution. According to its documentation, the normalizer receives the current module base path and the literal string supplied to `require`, then returns two strings for the new base and normalized module name. V8Js joins them with `/` before invoking the loader unless the module was already cached.

Exception and value conversion are also configurable. `setExceptionFilter()` receives an uncaught PHP exception that will be forwarded to JavaScript. `FLAG_PROPAGATE_PHP_EXCEPTIONS` affects propagation, while `FLAG_FORCE_ARRAY` requests array conversion behavior. These options matter because PHP arrays and JavaScript objects do not have identical semantics, and exception handling crosses two runtime models.

## Time, Memory, and Garbage-Collection Controls

Resource controls are explicit rather than implicit. `executeString()` and `executeScript()` accept optional time and memory limits. The API documentation says that exceeding these values produces `V8JsTimeLimitException` or `V8JsMemoryLimitException`. The same settings can be applied to a `V8Js` object through `setTimeLimit()` and `setMemoryLimit()`.

These controls address two different runaway patterns. A time limit bounds execution duration in milliseconds. A memory limit bounds V8 memory in bytes. An application can therefore choose the control that corresponds to its workload, although the README does not provide recommendations for calculating safe values for a particular script.

`setAverageObjectSize()` adds another V8-specific behavior. The README says it sets the average size used when V8's external memory total is adjusted for each exported object, and V8 triggers garbage collection when that adjusted total reaches 192 MB. This setting relates to exported PHP-backed objects. It should not be described as a global PHP process memory limit.

The API exposes pending exception state through `getPendingException()` and `clearPendingException()`. This gives PHP code a way to inspect and then clear an uncaught exception associated with the context. The README does not document whether a context remains fully reusable after every script or limit failure. It also does not document behavior for detached promises or background work after a synchronous call returns, so those cases fall outside the guarantees that can be established from the README.

The limits are useful containment mechanisms, but not a blanket security guarantee. The process still needs narrowly chosen operating-system privileges, and scripts still need application-level validation. That conclusion follows from the limited controls documented for this extension, not from a claim that V8 itself is insecure.

## Installing phpv8/v8js and Running a First Script

The main README does not give a single universal installation command. It requires PHP 8.0.0 or later and the V8 JavaScript engine library. V8 9.0 or later is required. GNU/Linux and MacOS users are directed to `README.Linux.md` and `README.MacOS.md` respectively. Windows users are directed to `README.Win32.md`, although the project states that Windows is not officially supported.

For an initial trial without performing the native build immediately, the README links to a prebuilt V8Js Docker image. The image is documented as containing V8, V8Js, and PHP CLI, with no Apache service. Because the exact image invocation is not provided in the main README, this article does not substitute an unverified command.

After installing and enabling the extension according to the applicable platform guide, the first script can be saved as `v8js-example.php`:

## First PHP-to-V8 Execution Example

This file creates a `V8Js` instance and executes JavaScript that adds two numbers. A successful script should print `3`, followed by a newline.

## Why the Installation Surface Is Larger Than a Normal PHP Package

phpv8/v8js is built as a native extension, not installed only as PHP source copied into an application directory. The repository contains C++ implementation files, a header for the extension, `config.m4`, and `config.w32`. The platform-specific README files contain the build route appropriate to each operating system.

The dependency boundary is larger than the PHP extension alone. The README requires a V8 library build and notes that releases are published quickly, with security support tied to Chrome's supported version lines and newer versions. That does not establish which exact V8 revision should be paired with every future phpv8/v8js build. It does show that choosing a V8 binary is part of deployment rather than an incidental setup detail.

The minimum requirements are PHP 8.0.0 or later and V8 9.0 or later. The repository has separate `php7` support, but the default branch described for this project is `php8`. That distinction matters when selecting instructions or a branch for an existing installation.

Windows presents the clearest packaging limitation. The README says support is not official and mentions missing maintainer time and Windows verification resources. The presence of `README.Win32.md` and `config.w32` means a build path exists in the repository, but it does not justify describing the platform as officially supported or binaries as readily available.

## phpv8/v8js Versus a Separate JavaScript Runtime

The main alternative is to run JavaScript in a separate runtime process and communicate with it from PHP. This architecture introduces another runtime, process lifecycle management, and an interface between the two programs. It can keep V8 outside the PHP worker, but that property depends on how the separate process is deployed and sandboxed. The repository does not compare phpv8/v8js with a specific alternative on performance or isolation, so no such claim is warranted.

phpv8/v8js takes the opposite integration approach. The extension embeds V8 in PHP and exposes contexts, scripts, values, limits, module callbacks, and exception controls through the PHP API. This is useful when JavaScript is one operation within PHP code and passing values across a process boundary would complicate that operation. It is a poor fit when the PHP application cannot accept native engine dependencies or manage a compiler and linked V8 library.

Node.js would suit a system designed around a JavaScript runtime as its primary environment, while phpv8/v8js is designed around JavaScript execution inside a PHP application. The README does not document Node.js compatibility, module interoperability, or benchmark results, so the distinction should remain architectural. The deciding question is whether direct PHP integration is worth the native deployment burden.

A separate process can also be considered when a team wants to isolate complete runtimes at the operating-system level, though its actual isolation depends on deployment controls outside phpv8/v8js. For phpv8/v8js, time and memory limits address resource runaway inside the embedded execution API. Neither approach should be assumed isolated without explicit process, account, filesystem, and network boundaries.

## Maintenance, Releases, and MIT Licensing

The repository is not archived, and its last push was on 2026-04-19. That is recent repository activity. The listed release history is older, however: version 2.1.1 was released on 2019-06-23, version 2.1.0 on 2018-01-07, and version 2.0.0 on 2017-11-26. Recent commits and old listed releases describe different signals and should not be conflated into a release cadence.

Upgrade planning must cover both layers. The extension needs compatibility with PHP, while its linked V8 library must satisfy the extension's stated minimum and the application's selected runtime behavior. The README also says V8 releases are published quickly. That makes rebuilding or tracking compatible engine versions an operational responsibility, although the repository does not publish a compatibility matrix in the API documentation.

The repository identifies the project as licensed under MIT. That permits use, modification, distribution, and sublicensing under the license's conditions, including preservation of its copyright and permission notice. The MIT license does not remove the need to comply with terms for V8 or other distributed dependencies. Anyone packaging binaries should inspect `LICENSE` and the provenance of the linked V8 build separately.

The upgrade cost is therefore concentrated in native packaging and compatibility checks, not ordinary application dependency installation. The README's linked Docker image may help exploration, but it contains PHP CLI rather than Apache and does not remove the need to define a production build strategy.

## Conclusion

Adopt phpv8/v8js when PHP must execute JavaScript in an embedded V8 context and the deployment can maintain libv8 and compile the extension. Do not choose it when you require officially supported Windows packaging or a runtime-free Composer installation. Verify PHP 8.0.0 or later, V8 9.0 or later, and the applicable instructions in README.Linux.md, README.MacOS.md, or README.Win32.md before committing to it.

## FAQ

### What is phpv8/v8js?

phpv8/v8js is a PHP extension that embeds Google's V8 JavaScript engine. It provides PHP methods for creating V8 contexts, executing scripts, applying limits, loading modules, and handling exceptions.

### What are the minimum requirements for phpv8/v8js?

The README requires PHP 8.0.0 or later and the V8 library at version 9.0 or higher. Platform-specific build guidance is divided among README.Linux.md, README.MacOS.md, and README.Win32.md.

### How does phpv8/v8js limit JavaScript execution?

`executeString()` and `executeScript()` accept a time limit in milliseconds and a memory limit in bytes. The API documentation says exceeding these limits throws `V8JsTimeLimitException` or `V8JsMemoryLimitException`.

### Does phpv8/v8js officially support Windows?

No. The README says Windows is not officially supported, although it provides separate build instructions in README.Win32.md.

### How does phpv8/v8js load JavaScript modules?

`setModuleLoader()` registers a PHP callable that receives a normalized module path and returns JavaScript source. `setModuleNormaliser()` can customize how require paths are normalized before loading.

## Sources

- [License: MIT](https://github.com/phpv8/v8js/blob/php8/LICENSE)
- [phpv8/v8js on GitHub](https://github.com/phpv8/v8js)
- [Project website](http://pecl.php.net/package/v8js)
- [README](https://github.com/phpv8/v8js/blob/php8/README.md)
- [Releases](https://github.com/phpv8/v8js/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/phpv8-v8js
