跪拜 Guibai
← All articles
Frontend · JavaScript

fun-ui 1.0 open-sources a Chromium-backed UI layer for the Fun language

By Funlang ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

For developers using niche languages or scripting runtimes, fun-ui demonstrates a low-cost path to modern web UIs without bundling a browser: reuse the OS's WebView2, keep the wire protocol small, and leave platform-specific code behind a host layer. The MIT license and Windows-only v1 make it a practical reference for hybrid UI architecture, not a general cross-platform solution yet.

Summary

fun-ui 1.0 is an open-source bridge that separates a Fun process from its UI. The Fun side keeps the window, arithmetic, file I/O, database calls, and native-library invocations, while the page runs in Chromium and only handles display and input. JavaScript calls Fun with jCAL and gets jRET back; Fun calls JavaScript with fCAL and gets fRET. All four messages are FD documents with a simple id/name/args/timeout shape, and handlers on the Fun side use a default fd_ prefix.

The transport comes in two flavors. WebView2 embeds Chromium directly in the Fun window through a small 32-bit Delphi DLL (built with Delphi 2006) that uses WebView4Delphi and the system's WebView2 Runtime. The second transport opens a local HTTP page on port 8278 and uses WebSocket; the window.Fun API is identical, so page code and dispatchers work unchanged. Binary payloads get a 4-byte little-endian length header with a raw-DEFLATE compression flag, enabled only above 512 bytes, and fCAL return values use a shared-buffer handle to avoid double copying.

Code size is tiny: 549 lines of Fun, 1631 lines of JavaScript, 375 lines of Delphi host. The first release only targets Windows and requires a Chromium-based browser due to CompressionStream and gbk text handling. The roadmap moves to a portable WebSocket server for external browsers, then native webview backends on Linux and macOS.

Takeaways
— fun-ui 1.0 is released under MIT, with the repository at https://github.com/funlang/fun-ui and release tagged v1.0.0.
— The message protocol uses four message types: jCAL (JS to Fun), jRET (Fun reply to JS), fCAL (Fun to JS), fRET (JS reply to Fun), all as FD documents with a type discriminator.
— Payloads are framed with a 4-byte little-endian length header; bit 31 set means the frame is raw-DEFLATE compressed. Compression is off by default and only considered above 512 bytes, with per-side toggles and thresholds.
— Bridge scripts tag FD text as gbk, not UTF-8, to preserve legacy Windows code pages and existing Fun strings; this requires a Chromium browser.
— fCAL return values use a shared buffer: Fun allocates a buffer, passes the handle to JS, JS writes the fRET and sends the handle back, avoiding double copies for large data.
— The WebView2 transport uses a 32-bit Delphi DLL (libwv2.dll, built with Delphi 2006) with only seven exported functions, relying on the system WebView2 Runtime.
— The WebSocket transport serves a local HTTP page on port 8278 using the same frame format; page code and dispatchers need no changes when switching bridges.
— Code totals 2555 lines (549 Fun, 1631 JS, 375 Delphi), 2853 with Chinese README and CHANGELOG.
— Version 1.0 is Windows-only, requires Fun 9.x, and needs a Chromium engine; the roadmap has four steps leading to Linux and macOS support via WebKitGTK and WKWebView.
— The protocol and JavaScript API are intended to stay stable, with platform-specific code isolated in the host layer.
Conclusions

The decision to ship a 32-bit Delphi 2006 DLL in 2026 is a pragmatic trade-off: WebView4Delphi offers the shortest path to a working host, and the author openly admits it, which signals that the project values getting a v1 out over architectural purity.

The gbk encoding choice is a backward-compatibility anchor that ties the entire UI stack to Chromium; it shows how legacy string handling can quietly dictate cross-platform portability.

The shared-buffer shortcut for fCAL returns is a clever performance detail in a project that otherwise keeps the protocol minimal, suggesting the author has real high-volume data transfer in mind.

The roadmap's second step (detaching Ui2Proxy from the WebView2 window) is the critical enabler for escaping Windows; without it, WebSocket is still a local loopback optimization rather than a cross-platform capability.

Concepts & terms
jCAL/jRET and fCAL/fRET
A four-message bidirectional calling convention between JavaScript and a Fun process. JavaScript-initiated calls are jCAL with jRET responses; Fun-initiated calls are fCAL with fRET responses. All messages are FD documents with a type field plus id, name, args, timeout (or id, val, err on replies).
raw DEFLATE with a length header
A binary framing scheme where each payload gets a 4-byte little-endian length prefix, and bit 31 of that prefix indicates whether the frame is compressed using raw DEFLATE (no zlib wrapper). Compression starts only above 512 bytes by default.
WebView2 Runtime
Microsoft's embedded browser control based on Chromium, available as a system component. Unlike bundling full Chromium, an app can load a small DLL and use the installed runtime, keeping the distribution footprint small.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗