Abstraction over WPE WebKit intended to be relatively Electron compatible
  • C++ 47.7%
  • TypeScript 22.8%
  • C 21.5%
  • Rust 6.9%
  • CMake 1.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-11-03 08:49:05 -05:00
src Initial commit 2026-11-03 08:49:05 -05:00
types Initial commit 2026-11-03 08:49:05 -05:00
typescript Initial commit 2026-11-03 08:49:05 -05:00
wpe Initial commit 2026-11-03 08:49:05 -05:00
.gitignore Initial commit 2026-11-03 08:49:05 -05:00
bun.lock Initial commit 2026-11-03 08:49:05 -05:00
Cargo.lock Initial commit 2026-11-03 08:49:05 -05:00
Cargo.toml Initial commit 2026-11-03 08:49:05 -05:00
package.json Initial commit 2026-11-03 08:49:05 -05:00
README.md Initial commit 2026-11-03 08:49:05 -05:00

Wosh

Wosh is a general-purpose application framework built around WPE WebKit and JavaScriptCore. Its job is to provide a compact runtime and extension model, not to prescribe desktop features for every application.

Wosh defines a transport-neutral JSON-RPC protocol, app permissions, pluggable API extensions, and frame descriptors for DMA-BUF, shared memory, and SharedArrayBuffer. Native file descriptors travel separately from JSON metadata. The TypeScript package provides browser-shell APIs over a host transport. Hosts implement the methods that applications use.

TypeScript usage

import { createWoshRuntime } from '@wo/wosh';

const { app, BrowserWindow, ipcRenderer, Menu, protocol } = createWoshRuntime({
  manifest,
  transport,
});

await app.whenReady();
const window = new BrowserWindow({ width: 960, height: 680, show: false });
await window.loadURL('https://example.org');
await window.show();

The web API talks only to the injected transport. It does not provide Node.js, shell, or unrestricted filesystem access. Host implementations decide which core operations they support and authorize each registered method against the app manifest.

WoshJsonRpcTransport supplies request IDs, bounded in-flight calls, timeouts, response correlation, and notification subscriptions over any host framing. The framing adapter only needs to send JSON messages and pass decoded messages to receive, so Unix sockets, pipes, and in-process transports share the same request behavior.

The TypeScript package also exposes host-mediated dialogs, shell URI and file actions, and encrypted string storage. Wosh does not select a desktop toolkit, shell command, or secret-storage backend.

Wo currently provides a separate WoshWoHost facade for its implemented compositor methods. It covers compositor status and quit, window snapshots and actions, application discovery and launch, directory and file reads, notifications, system actions, D-Bus calls, and Thunderbird mail snapshots. Those methods use the wo.* namespace and are routed over the WPE launcher's JSON-RPC stdio bridge. host.notify() messages are accepted as JSON-RPC notifications, and Wo does not send responses to them.

Wo's WPE runtime injects only a generic page transport before the configured JavaScript extension source. The source is supplied through a window's js configuration field and can use window.wosh.host for host RPC, notifications, and event subscriptions. Clients can build their own APIs on that transport. The WPE runtime does not define compositor, desktop, portal, audio, or other Wo-specific feature APIs.

The framework surface maps to host-registered namespaces. The TypeScript client defines app, window, webContents, ipc, session, menu, protocol, screen, and nativeTheme. Wo's WPE host does not yet implement all of those namespaces, including multi-window creation, native menus, session storage, and screen queries. The Rust API registry supports host-side discovery and capability checks, but the WPE launcher does not yet use that registry for these browser-shell calls.

The frame descriptors are the import/export contract. They carry buffer layout, format, modifier, plane offsets, strides, fence handles, or shared-memory sequence metadata. Generic importer and exporter traits let renderer bindings move DMA-BUF and SHM handles without baking a specific compositor into Wosh. The TypeScript frame transport defines matching import, export, and SharedArrayBuffer mapping hooks. wosh/wpe provides a C ABI runtime for WPEWebView lifecycle, navigation, per-partition network sessions, top-level window controls, JavaScript evaluation, pointer, keyboard, scroll, and touch input, focus and resize synchronization, and a generic page IPC bridge. Its rendered/released buffer callbacks can export duplicated DMA-BUF file descriptors or referenced shared-memory bytes. The WPE buffer itself is borrowed during the callback. Hosts can register custom URI schemes and answer requests asynchronously, mediate navigation, resolve browser permission requests, and complete file chooser requests. WPEPlatform owns the Wayland surface and its input path. Wo manages that surface through Smithay and uses the JSON-RPC process bridge for native calls. The WPE runtime explicitly enables WebGL. The Wo launcher selects WPEPlatform's Wayland backend and requires EGL initialization plus negotiated DMA-BUF rendering formats. WPE's Wayland backend rejects shared-memory output. Its own shell page renders to the internal WPE Wayland surface, which is presented as the shell window. Native application surfaces follow a separate route and remain website-owned. The compositor forwards their DMA-BUF plane descriptors and FDs to the WPE page. The page imports them through the patched WebGL API, then WPE's GPU process creates EGLImages and binds them to page WebGL textures. This keeps window composition inside the website and avoids a compositor-side app-surface renderer. Multi-plane buffers preserve each plane's FD, offset, stride, and modifier. Shared-memory clients use a page-side upload path. Unsupported DMA-BUF formats report an import error rather than silently appearing blank.

WPE 2.54 and newer is the target. WPEPlatform is the integration surface for Wayland, DRM, and headless rendering, while JavaScriptCore ships as part of WPE. just build-wosh-wpe builds the reusable runtime library and minimal standalone launcher when WPE development packages are installed. Wosh will not patch a second JavaScript engine into WebKit.

When used as Wo's desktop root, the launcher connects to Wo's native surface stream. DMA-BUF planes and SHM file descriptors arrive over SCM_RIGHTS and are handed to the WPE page through WebKit's page-message FD list. App surface bytes never travel through JSON-RPC. The C++ runtime build uses CCache when available through packaging/build-wosh-wpe.sh.