KDE applications are Qt applications, and Kirigami (part of KDE Frameworks 6) is a QML module. As with Qt, bun:ffi loads a small extern "C" shim: it creates a QQmlApplicationEngine, loads a Kirigami.ApplicationWindow and runs QApplication::exec().
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QVariantMap>
static const char qml[] = R"(
import QtQuick
import QtQuick.Controls as Controls
import org.kde.kirigami as Kirigami
Kirigami.ApplicationWindow {
pageStack.initialPage: Kirigami.Page {
title: "Kirigami through bun:ffi"
Controls.Label { text: "Hello from Bun" }
}
}
)";
extern "C" int bun_kirigami_window_run(const char* title, int width, int height) {
static int argc = 1;
static char arg0[] = "bun";
static char* argv[] = {arg0, nullptr};
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.setInitialProperties({
{"title", QString::fromUtf8(title)}, {"width", width}, {"height", height}, {"visible", true},
});
// A qrc: URL keeps loading synchronous, so rootObjects() is ready right away.
engine.loadData(qml, QUrl(QStringLiteral("qrc:/window.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
c++ -std=c++20 -shared -fPIC -o libshim.so shim.cpp $(pkg-config --cflags --libs Qt6Widgets Qt6Quick Qt6Qml)
import { dlopen, FFIType } from "bun:ffi";
const { symbols } = dlopen("./libshim.so", {
bun_kirigami_window_run: { args: [FFIType.ptr, FFIType.i32, FFIType.i32], returns: FFIType.i32 },
});
process.exit(symbols.bun_kirigami_window_run(Buffer.from("Hello from Bun\0"), 640, 400));
bun window.ts
Kirigami is a runtime dependency only: the shim links Qt Quick and Qt QML, and the engine imports org.kde.kirigami when it loads the QML. Install it with your distribution's kirigami package, or on Windows with MSYS2 (pacman -S mingw-w64-ucrt-x86_64-kirigami, with C:\msys64\ucrt64\bin on PATH). Without a display, set QT_QPA_PLATFORM=offscreen and QT_QUICK_BACKEND=software.
Tested platforms
The fixture prints window created and window closed with exit code 0 on:
- Windows 11: Kirigami 6.30.0 from MSYS2 UCRT64
- Ubuntu 26.04: Kirigami 6.24.0 under
xvfb-run
The Linux images are scripts/aphrody/gui/ubuntu.Dockerfile and scripts/aphrody/gui/alpine.Dockerfile.
A fuller version with a JSCallback for window creation, an Escape shortcut, --timeout, and --title, --width and --height options lives in the Bun repository at test/js/bun/ffi/kde-window.fixture.ts.
See Docs > Runtime > FFI for the full bun:ffi reference.