Foreign engines — Firefox & Servo
The Chromium family (Chrome / Chromium / Edge) is driven in-process through shirabe's own CDP engine. Firefox and Servo take a different path: their cores are huge, so we let the browser vendors (or anyone building those cores) compile a tiny adapter against a fixed C ABI and ship it as a dynamic library — the same model ort uses for ONNX Runtime. shirabe is the "thin C-binding wrapper": it dlopens the vendor lib and routes calls through a generic Engine trait.
your app ── shirabe (CDP engine) ── Chrome / Chromium / Edge (in-process)
└─ shirabe (FFI wrapper) ── libshirabe_engine_firefox ── Firefox core
└ libshirabe_engine_servo ── Servo core
Enabling
shirabe = { version = "0.1", features = ["foreign-engine"] }
Then select a foreign backend:
SHIRABE_BACKEND=firefox
SHIRABE_BACKEND=servo
The C ABI a vendor lib exports
typedef struct shirabe_engine shirabe_engine;
shirabe_engine *; /* JSON opts */
void ;
int ;
char *; /* JSON out */
void ;
int ; /* PNG */
void ;
const char *; /* "firefox" … */
A few hundred lines of adapter code against this ABI is enough to drive a whole browser core; everything shirabe exposes over HTTP is built on these five operations.
Where the lib comes from
CdylibEngine::open looks for libshirabe_engine_<id>.{so,dylib,dll} in:
- 1SHIRABE_ENGINE_PATH — explicit override.
- 2next to the current executable.
- 3<cache>/shirabe/engines/<id>/ — where the release-fetch step places downloaded copies (a release workflow publishes prebuilt libs to GitHub Releases under their own tags).
Until a vendor publishes a lib, selecting Firefox/Servo returns a clear error pointing at the FFI contract — shirabe never tries to spawn firefox as if it spoke CDP.