Owncast embeds one interpreter engine per language, QuickJS for JavaScript and CPython for Python, compiled to WebAssembly. The host compiles each engine once and instantiates it per plugin (injecting the plugin's source via Extism config), instead of every plugin shipping its own interpreter. See ../docs/ARCHITECTURE.md.
These engine.wasm files are build artifacts committed into the Owncast repo
at services/plugins/engines/<language>/engine.wasm and pulled in with
go:embed, so Owncast's Go build never runs this (JS/Python) toolchain. When you
change the engine, you regenerate the wasm here and commit it in the Owncast
repo.
Regenerate whenever any of these change:
- the SDK runtime (
sdks/js/index.jsorsdks/python/owncast_plugin/__init__.py), which is bundled into the engine, - the engine bootstrap,
engines/javascript/entry.js(JS) or the bootstrap inengines/build_py.py(Python), - the host-import union (
engines/javascript/engine.d.ts/ the Python build's import block), i.e. when a host function is added or removed.
You do not regenerate engines to publish a plugin. Author plugins ship source and run on whatever engine the host already embeds.
- Node (this repo uses 24.x).
makefetches the JS engine toolchain (extism-js+ binaryen) itself intoengines/.toolchain/viainstall-toolchain.mjs. You do not neednpm installfor this, and the author-facing@owncast/plugin-sdkinstall no longer downloads any wasm tooling. - Python 3 and the
extism-pytoolchain. The Python SDK fetches it on first use. Running any Python plugin build once (orowncast-plugin-py build) populates~/.cache/owncast-plugin-sdk/. Override the binary withEXTISM_PY.
cd engines
make # both engines → ../owncast/services/plugins/engines/{javascript,python}/engine.wasm
make js # JavaScript only
make python # Python onlyThe default output target is a sibling ../owncast checkout. Point it elsewhere
with OWNCAST_ENGINE_DIR (the directory that holds the javascript/ and
python/ subdirs), or pass a directory as the first arg to build.mjs /
build_py.py.
- Commit the changed
engine.wasmin the Owncast repo (that's where they're embedded). Keep them in sync with the SDK runtime version the manifestapifield gates on. - The
owncast-plugin-test/owncast-plugin-servebinaries embed the engines (via the imported runtime), so rebuild them to test the new engine:cd ../host-runtime && go build -o owncast-plugin-test ./cmd/owncast-plugin-test/
- Rebuild your example plugins and run the test suite to verify nothing broke in either language.