A module is one manifest, a sandboxed UI, and a permissioned bridge to the desktop. Build a small app, publish it to the Module Store, and it runs in every user's window. No prior experience assumed.
Starter manifest, a UI shell and a sample input.
The same rules the backend runs on upload.
A safety-scanned, upload-ready zip.
Upload, admin review, then the Module Store.
Your UI reaches the desktop only through declared, scoped capabilities — the SDK turns that protocol into plain await calls. Tap one:
const hanabi = createHanabiClient();
const ctx = await hanabi.ready();
// → { user, theme, accent, windowId } The platform ships continuously. Here's the latest, plus where the roadmap stands.
Modules can now (with permission) integrate with the desktop workspace and manage the virtual filesystem beyond their own folder.
The Developer Portal now has a debug console that streams a running module's bridge requests and replies (including any error code) so yo…
A draft that declares a heavy capability (worker.native for the ffmpeg/imagemagick/libvips image, or network.fetch.broad for open-web fet…
Your UI runs in an opaque-origin iframe and reaches the platform only through the capability bridge — every
call declared, granted, and scoped. The SDK turns that protocol into plain await calls.
import { createHanabiClient } from '@hanabi/module-sdk'; const hanabi = createHanabiClient(); const ctx = await hanabi.ready(); // read context const { files } = await hanabi.pickFile(['xlsx']); // files.read const file = await hanabi.readFile(files[0].id); // file.bytesB64 await hanabi.writeFile('result.csv', out); // files.write