Extism lets you write WASM extensions for applications written in almost any language. Here's how to use Extism to write extendable programs and plugins. Credit: locrifa/Shutterstock WebAssembly was originally designed to give in-browser web applications a way to run portable, sandboxed, high-performance binaries. As WASM matures beyond the browser, new uses for the technology are emerging. Using WASM to build programmability and extensibility into applications is one use case that is gathering steam. The Extism software library lets you write programs that can interface with extensions written in WebAssembly. Extism handles the data and function-calling interface between code written in your host application and the WASM extensions. This lets you focus on writing the functionality in your application and extensions, rather than dealing manually with WASM’s data types or calling conventions. Writing an Extism-powered app The Extism library works with just about any widely-used language. Currently, it supports C/C++, Java, JavaScript, Go, Rust, Ruby, Python, the .NET language family (C# and F#, in particular), Elixir, PHP, OCaml, Zig, Haskell, and D. Since the library itself is written in Rust and exposes a C-types interface, any language with a C foreign-function interface can support Extism with a little work. Plugins, or WASM extensions, can be written in any language that compiles to WASM. Rust is an obvious choice, being the language Extism is written in, but developers can use AssemblyScript (which compiles directly to WASM), or JavaScript, Go, C#, F#, C, Haskell, or Zig. Extism’s philosophy is to support writing programs in such a way that their functionality can be freely extended with plugins written in WASM. This extensibility can be as shallow or deep as you like. Extism’s WASM runtime also automatically handles things like sandboxing execution and memory access. As such, it provides more process protection than other solutions you might use to expand a program’s functionality, like embedding a Lua interpreter. Example of an Extism plugin Here’s a simple example of an Extism plugin and a host application that uses it. The plugin has a single function, greet, which takes in a string and returns a greeting using the supplied string. This incarnation of the plugin (also adapted from Extism’s docs) is written in AssemblyScript for simplicity: import { Host } from '@extism/as-pdk'; export function greet(): i32 { let name = Host.inputString(); let output = `Hello, ${name}!`; Host.outputString(output); return 0; } The Extism plugin development kit, or PDK, supplies objects we use to create interfaces with the outside world. The Host object contains various abstractions for taking input from the host and returning it in different formats—in this case, strings. Another option is to take in and return JSON, since that’s a convenient way to handle structured data in Extism, but strings work for this example. We also need to define which functions in our plugin are available externally. This varies between languages, but in AssemblyScript it’s done through the export keyword. We could also define advanced error-handling features—for instance, a function to call if the plugin itself throws an error—but we’ll leave that out for simplicity. Example of an Extism app To write an application that uses an Extism plugin, you use the Extism library for the language you’re using to write the application. For this example, we’ll use Python, since both the language and the way Extism works with it are quite simple. Here’s the Python program we’re using to work with this plugin: import extism manifest = {"wasm": [{"path":"myplugin/example.wasm"}]} plugin = extism.Plugin(manifest) def greet(text: str): return plugin.call("greet", text) print(greet("Jeffrey")) Run this and you’ll get back the response: Hello, Jeffrey! To use our plugin, we need to create a manifest—a Python dictionary, in this case—that describes where the plugin can be found (here, it’s in a project subdirectory called myplugin). Manifests can also be used to describe other behaviors, like how much memory the plugin can allocate, or what paths on disk it is permitted to use. Once we create an object to represent the plugin, we can make function calls to it using the .call() method. Note that this simple example only works for a single, predetermined plugin. If your application wants to accept arbitrary plugins, it’ll need to define interfaces to hook the plugins into. It can then either discover the presence of plugins automatically or use some kind of user-supplied metadata. Conclusion Extism, like WASM itself, is relatively young and its best use cases are still evolving. With its low barrier to entry for both writing WASM plugins and creating applications that use them, Extism is a useful way to experiment with WASM outside the browser. You’ll reap the rewards in discovery and dividends. Related content news Wasmer WebAssembly platform now backs iOS Wasmer 5.0 release also features improved performance, a leaner codebase, and discontinued support for the Emscripten toolchain. By Paul Krill Oct 30, 2024 2 mins Mobile Development Web Development Software Development news analysis What Entrust certificate distrust means for developers Secure communications between web browsers and web servers depend on digital certificates backed by certificate authorities. What if the web browsers stop trusting your CA? By Travis Van Oct 30, 2024 9 mins Browser Security Web Development Application Security news Next.js 15 arrives with faster bundler High-performance Rust-based Turbopack bundler moves from beta to stable with the latest update of the React-based web framework. By Paul Krill Oct 24, 2024 2 mins JavaScript React Web Development feature WasmGC and the future of front-end Java development WebAssembly’s garbage collection extension makes it easier to run languages like Java on the front end. Could it be the start of a new era in web development? By Matthew Tyson Oct 16, 2024 10 mins Web Development Software Development Resources Videos