PHPackages                             extism/extism - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. extism/extism

ActiveLibrary[Framework](/categories/framework)

extism/extism
=============

Make your software programmable. Run WebAssembly extensions in your app using the first off-the-shelf, universal plug-in system.

v1.9.1(1y ago)303.0k↑45%51BSD-3-ClausePHPPHP ^7.4 || ^8

Since Nov 16Pushed 1y ago5 watchersCompare

[ Source](https://github.com/extism/php-sdk)[ Packagist](https://packagist.org/packages/extism/extism)[ RSS](/packages/extism-extism/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (4)Dependencies (3)Versions (6)Used By (1)

Extism PHP Host SDK
===================

[](#extism-php-host-sdk)

This repo houses the PHP SDK for integrating with the [Extism](https://extism.org/) runtime. Install this library into your host PHP applications to run Extism plugins.

Installation
------------

[](#installation)

### Install the Extism Runtime Dependency

[](#install-the-extism-runtime-dependency)

For this library, you first need to install the Extism Runtime. You can [download the shared object directly from a release](https://github.com/extism/extism/releases) or use the [Extism CLI](https://github.com/extism/cli) to install it:

```
sudo extism lib install latest

#=> Fetching https://github.com/extism/extism/releases/download/v0.5.2/libextism-aarch64-apple-darwin-v0.5.2.tar.gz
#=> Copying libextism.dylib to /usr/local/lib/libextism.dylib
#=> Copying extism.h to /usr/local/include/extism.h
```

> **Note**: This library has breaking changes and targets 1.0 of the runtime. For the time being, install the runtime from our nightly development builds on git: `sudo extism lib install --version git`.

### Install the Package

[](#install-the-package)

Install via [Packagist](https://packagist.org/):

```
composer require extism/extism
```

*Note*: For the time being you may need to add a minimum-stability of "dev" to your composer.json

```
{
   "minimum-stability": "dev",
}
```

Getting Started
---------------

[](#getting-started)

This guide should walk you through some of the concepts in Extism and this PHP library.

First you should add a using statement for Extism:

```
use Extism\Plugin;
use Extism\Manifest;
use Extism\Manifest\UrlWasmSource;
```

Creating A Plug-in
------------------

[](#creating-a-plug-in)

The primary concept in Extism is the [plug-in](https://extism.org/docs/concepts/plug-in). You can think of a plug-in as a code module stored in a `.wasm` file.

Since you may not have an Extism plug-in on hand to test, let's load a demo plug-in from the web:

```
$wasm = new UrlWasmSource("https://github.com/extism/plugins/releases/latest/download/count_vowels.wasm");
$manifest = new Manifest($wasm);

$plugin = new Plugin($manifest, true);
```

> **Note**: The schema for this manifest can be found here:

### Calling A Plug-in's Exports

[](#calling-a-plug-ins-exports)

This plug-in was written in Rust and it does one thing, it counts vowels in a string. As such, it exposes one "export" function: `count_vowels`. We can call exports using `Plugin.call`:

```
$output = $plugin->call("count_vowels", "Hello, World!");

// => {"count": 3, "total": 3, "vowels": "aeiouAEIOU"}
```

All exports have a simple interface of optional bytes in, and optional bytes out. This plug-in happens to take a string and return a JSON encoded string with a report of results.

### Plug-in State

[](#plug-in-state)

Plug-ins may be stateful or stateless. Plug-ins can maintain state b/w calls by the use of variables. Our count vowels plug-in remembers the total number of vowels it's ever counted in the "total" key in the result. You can see this by making subsequent calls to the export:

```
$output = $plugin->call("count_vowels", "Hello, World!");
// => {"count": 3, "total": 6, "vowels": "aeiouAEIOU"}

$output = $plugin->call("count_vowels", "Hello, World!");
// => {"count": 3, "total": 9, "vowels": "aeiouAEIOU"}
```

These variables will persist until this plug-in is freed or you initialize a new one.

### Configuration

[](#configuration)

Plug-ins may optionally take a configuration object. This is a static way to configure the plug-in. Our count-vowels plugin takes an optional configuration to change out which characters are considered vowels. Example:

```
$wasm = new UrlWasmSource("https://github.com/extism/plugins/releases/latest/download/count_vowels.wasm");

$manifest = new Manifest($wasm);

$plugin = new Plugin($manifest, true);
$output = $plugin->call("count_vowels", "Yellow, World!");
// => {"count": 3, "total": 3, "vowels": "aeiouAEIOU"}

$manifest = new Manifest($wasm);
$manifest->config->vowels = "aeiouyAEIOUY";

$plugin = new Plugin($manifest, true);
$output = $plugin->call("count_vowels", "Yellow, World!");
// => {"count": 4, "total": 4, "vowels": "aeiouAEIOUY"}
```

### Host Functions

[](#host-functions)

> **Note**
>
> Host Functions support is experimental. Due to usage of callbacks with FFI, It may leak memory.

Let's extend our count-vowels example a little bit: Instead of storing the `total` in an ephemeral plug-in var, let's store it in a persistent key-value store!

Wasm can't use our KV store on it's own. This is where `Host Functions` come in.

[Host functions](https://extism.org/docs/concepts/host-functions) allow us to grant new capabilities to our plug-ins from our application. They are simply some PHP functions you write which can be passed down and invoked from any language inside the plug-in.

Let's load the manifest like usual but load up this `count_vowels_kvstore` plug-in:

```
$manifest = new Manifest(new UrlWasmSource("https://github.com/extism/plugins/releases/latest/download/count_vowels_kvstore.wasm"));
```

> *Note*: The source code for this is [here](https://github.com/extism/plugins/blob/main/count_vowels_kvstore/src/lib.rs) and is written in rust, but it could be written in any of our PDK languages.

Unlike our previous plug-in, this plug-in expects you to provide host functions that satisfy our import interface for a KV store.

We want to expose two functions to our plugin, `void kv_write(key string, value byte[])` which writes a bytes value to a key and `byte[] kv_read(key string)` which reads the bytes at the given `key`.

```
// pretend this is Redis or something :)
$kvstore = [];
$kvRead = new HostFunction("kv_read", [ExtismValType::I64], [ExtismValType::I64], function (string $key) use (&$kvstore) {
    $value = $kvstore[$key] ?? "\0\0\0\0";

    echo "Read " . bytesToInt($value) . " from key=$key" . PHP_EOL;
    return $value;
});

$kvWrite = new HostFunction("kv_write", [ExtismValType::I64, ExtismValType::I64], [], function (string $key, string $value) use (&$kvstore) {
    echo "Writing value=" . bytesToInt($value) . " from key=$key" . PHP_EOL;
    $kvstore[$key] = $value;
});

function bytesToInt(string $bytes): int {
    $result = unpack("L", $bytes);
    return $result[1];
}
```

> *Note*: The plugin provides memory pointers, which the SDK automatically converts into a `string`. Similarly, when a host function returns a `string`, the SDK allocates it in the plugin memory and provides a pointer back to the plugin. For manual memory management, request `CurrentPlugin` as the first parameter of the host function. For example:
>
> ```
> $kvRead = new HostFunction("kv_read", [ExtismValType::I64], [ExtismValType::I64], function (CurrentPlugin $p, int $keyPtr) use ($kvstore) {
>   $key = $p->read_block($keyPtr);
>
>   $value = $kvstore[$key] ?? "\0\0\0\0";
>
>   return $p->write_block($value);
> });
> ```

We need to pass these imports to the plug-in to create them. All imports of a plug-in must be satisfied for it to be initialized:

```
$plugin = new Plugin($manifest, true, [$kvRead, $kvWrite]);

$output = $plugin->call("count_vowels", "Hello World!");

echo($output . PHP_EOL);
// => Read 0 from key=count-vowels"
// => Writing value=3 from key=count-vowels"
// => {"count": 3, "total": 3, "vowels": "aeiouAEIOU"}

$output = $plugin->call("count_vowels", "Hello World!");

echo($output . PHP_EOL);
// => Read 3 from key=count-vowels"
// => Writing value=6 from key=count-vowels"
// => {"count": 3, "total": 6, "vowels": "aeiouAEIOU"}
```

For host function callbacks, these are the valid parameter types:

- `CurrentPlugin`: Only if its the first parameter. Allows you to manually manage memory. Optional.
- `string`: If the parameter represents a memory offset (an `i64`), then the SDK can automatically load the buffer into a `string` for you.
- `int`: For `i32` and `i64` parameters.
- `float`: For `f32` and `f64` parameters.

Valid return types:

- `void`
- `int`: For `i32` and `i64` parameters.
- `float`: For `f32` and `f64` parameters.
- `string`: the content of the string will be allocated in the wasm plugin memory and the offset (`i64`) will be returned.

### Fuel Limits

[](#fuel-limits)

Plugins can be initialized with a fuel limit to constrain their execution. When a plugin runs out of fuel, it will throw an exception. This is useful for preventing infinite loops or limiting resource usage.

```
// Create plugin with fuel limit of 1000 instructions
$plugin = new Plugin($manifest, true, [], new PluginOptions(true, 1000));

try {
    $output = $plugin->call("run_test", "");
} catch (\Exception $e) {
    // Plugin ran out of fuel
    // The exception message will contain "fuel"
}
```

### Call Host Context

[](#call-host-context)

Call Host Context provides a way to pass per-call context data when invoking a plugin function. This is useful when you need to provide data specific to a particular function call rather than data that persists across all calls.

Here's an example of using call host context to implement a multi-user key-value store where each user has their own isolated storage:

```
$multiUserKvStore = [[]];

$kvRead = new HostFunction("kv_read", [ExtismValType::I64], [ExtismValType::I64], function (CurrentPlugin $p, string $key) use (&$multiUserKvStore) {
    $userId = $p->getCallHostContext(); // get a copy of the host context data
    $kvStore = $multiUserKvStore[$userId] ?? [];

    return $kvStore[$key] ?? "\0\0\0\0";
});

$kvWrite = new HostFunction("kv_write", [ExtismValType::I64, ExtismValType::I64], [], function (CurrentPlugin $p, string $key, string $value) use (&$multiUserKvStore) {
    $userId = $p->getCallHostContext(); // get a copy of the host context data
    $kvStore = $multiUserKvStore[$userId] ?? [];

    $kvStore[$key] = $value;
    $multiUserKvStore[$userId] = $kvStore;
});

$plugin = self::loadPlugin("count_vowels_kvstore.wasm", [$kvRead, $kvWrite]);

$userId = 1;

$response = $plugin->callWithContext("count_vowels", "Hello World!", $userId);
$this->assertEquals('{"count":3,"total":3,"vowels":"aeiouAEIOU"}', $response);

$response = $plugin->callWithContext("count_vowels", "Hello World!", $userId);
$this->assertEquals('{"count":3,"total":6,"vowels":"aeiouAEIOU"}', $response);
```

Note: Unlike some other language SDKS, in the Extism PHP SDK the host context is copied when accessed via `getCallHostContext()`. This means that modifications to the context object within host functions won't affect the original context object passed to `callWithContext()`.

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance39

Infrequent updates — may be unmaintained

Popularity33

Limited adoption so far

Community21

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~115 days

Total

4

Last Release

518d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/04c409f0ca9a22992ce24b7f59ee7fbc7ac976a2bf406097f04f7c66aa064c27?d=identicon)[extism](/maintainers/extism)

---

Top Contributors

[![bhelx](https://avatars.githubusercontent.com/u/185919?v=4)](https://github.com/bhelx "bhelx (17 commits)")[![nilslice](https://avatars.githubusercontent.com/u/7517515?v=4)](https://github.com/nilslice "nilslice (16 commits)")[![mhmd-azeez](https://avatars.githubusercontent.com/u/16880059?v=4)](https://github.com/mhmd-azeez "mhmd-azeez (6 commits)")[![zshipko](https://avatars.githubusercontent.com/u/332534?v=4)](https://github.com/zshipko "zshipko (4 commits)")[![oatmael](https://avatars.githubusercontent.com/u/45870261?v=4)](https://github.com/oatmael "oatmael (2 commits)")[![G4Vi](https://avatars.githubusercontent.com/u/2080147?v=4)](https://github.com/G4Vi "G4Vi (1 commits)")[![davidbuzz](https://avatars.githubusercontent.com/u/174009?v=4)](https://github.com/davidbuzz "davidbuzz (1 commits)")[![yigitcukuren](https://avatars.githubusercontent.com/u/42731194?v=4)](https://github.com/yigitcukuren "yigitcukuren (1 commits)")

---

Tags

frameworkruntimeplug-inplugin-systemwebassemblywasm

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/extism-extism/health.svg)

```
[![Health](https://phpackages.com/badges/extism-extism/health.svg)](https://phpackages.com/packages/extism-extism)
```

###  Alternatives

[viames/pair

lightweight PHP framework as the air

103.0k1](/packages/viames-pair)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
