A thin OCaml binding to webview: open a native window backed by the operating system's web engine, load HTML/CSS/JS, and bridge JavaScript with OCaml — no Electron, no bundler.
The owebview package installs two libraries, and the split is deliberate.
owebview — module Webview. The binding proper: the complete webview 0.12 C API and nothing else. It stays thin on purpose, and leaves higher-level conveniences (JSON for the bridge, for instance) to the caller.owebview.desktop — module Webview_desktop. Everything a native application needs around the web view: finding its assets on disk, its icon in the Dock, the system's modal dialogs, the menu bar. None of it is part of the webview API — it calls Cocoa, GTK and Win32 directly, and its C stubs include no part of webview.h. It reaches the window through Webview.get_window, like any other user of the binding could.Depend on the first alone for a window whose content is an inline HTML string; add the second as soon as the page comes from files on disk:
(executable
(name main)
(libraries owebview owebview.desktop))A whole application is about ten lines:
let () =
let w = Webview.create () in
Webview.set_title w "My first owebview app";
Webview.set_size w ~width:480 ~height:320 Webview.Hint_none;
Webview.set_html w "<h1>Hello from OCaml</h1>";
Webview.run w;
Webview.destroy wCall OCaml from the page and answer the JavaScript promise:
Webview.bind w "add" (fun id req ->
let result =
match Scanf.sscanf_opt req "[%d,%d]" (fun a b -> a + b) with
| Some n -> string_of_int n
| None -> "null"
in
Webview.return w id ~error:false ~result)Load a real page, with its CSS and images, from a directory next to the executable:
let index =
Filename.concat (Webview_desktop.Locate_assets.web_dir ()) "index.html"
in
Webview.navigate w ("file://" ^ index)A step-by-step tutorial builds this up from a first window to a complete application.
owebview: the webview bindingThe whole binding is the Webview module. A tour of it:
Webview.create, Webview.run, Webview.terminate, Webview.destroyWebview.set_title, Webview.set_sizeWebview.navigate, Webview.set_html, Webview.init, Webview.evalWebview.bind, Webview.return, Webview.unbindWebview.dispatch, the one safe way to drive the window from another threadWebview.get_window, Webview.get_native_handleowebview.desktop: native desktop integrationFour independent modules under Webview_desktop:
Webview_desktop.Locate_assets — find the application's web/ directory relative to the executable rather than the current working directory, so a page loads the same under dune exec, from an installed binary, or from a Dock icon. Webview_desktop.Locate_assets.web_dir is the one to call.Webview_desktop.Icon — give a plain executable a real icon instead of the generic one: Webview_desktop.Icon.set_app_icon for the Dock, taskbar or switcher, and Webview_desktop.Icon.set_app_id for the application id a Wayland desktop matches against an installed .desktop file.Webview_desktop.Dialog — the system's own modal dialogs: Webview_desktop.Dialog.confirm, Webview_desktop.Dialog.open_file and Webview_desktop.Dialog.open_directory. They block until the user answers and must run on the UI thread, which makes a binding callback their natural home.Webview_desktop.Menu — the native menu bar, described as an ordinary OCaml value and installed with Webview_desktop.Menu.set, with keyboard accelerators and per-item callbacks.Each module's own page documents what differs between platforms, which is where the real detail lives: macOS runs the menu bar and the Dock icon application-globally, Linux needs a .desktop file under Wayland, and GTK 4 supports neither the dialogs nor the menu bar.
webview uses the system web engine, so building against it needs that engine's development files. Only Windows asks anything of you:
gtk+-3.0 and webkit2gtk-4.1 (the -dev packages). They come from the conf-gtk3-webkit opam package, so opam install offers to install them for your distribution.nuget install Microsoft.Web.WebView2; the build finds WebView2.h in the NuGet cache on its own. The WebView2 runtime itself needs nothing — it ships with Windows 10 and 11.owebview.desktop needs strictly less — the platform toolkit without the web engine — so it adds nothing to install. The platform-specific compile and link flags of both libraries are detected automatically at build time, and there is nothing to tweak by hand.