[ANN] ocgtk 0.1: OCaml bindings for GTK 4 (preview release)

I’m pleased to announce the first preview release of ocgtk, OCaml bindings for GTK 4 (v0.1-preview0).

What is it?

ocgtk provides OCaml bindings for the GTK 4 widget toolkit and its associated libraries (GDK, GIO,
Pango, GdkPixbuf, GSK, Graphene, Cairo). It targets OCaml >=5.3 (for now).

It is inspired by, and draws some core common code and many design ideas from, lablgtk3 — the long-standing GTK 3 bindings library. However, the APIs are not compatible: whereas lablgtk3’s bindings are largely hand-written, ocgtk uses a code generator that reads GObject Introspection (GIR) definition files to produce both C stubs and OCaml wrappers. This means binding coverage tracks the GIR definitions rather than hand-written effort, and the generated code follows a consistent procedural structure.

A note on tooling: the code generator itself was developed with heavy assistance from LLMs. However, the output (the C stubs and OCaml modules that form the actual library) is programmatically generated from the GIR definitions, not written by an LLM.

What’s implemented

  • Bindings for GTK 4, GDK, GIO, Pango, GdkPixbuf, GSK, Graphene, and Cairo
  • Classes, records, enumerations, and bitfields
  • Constructors, methods, and properties
  • Signals (no return values or parameters)
  • A working example: a GTK 4 calculator application

What’s missing

This is a first milestone, not a production-ready release. Several important features are not yet
supported:

  • Interfaces: GObject interfaces are not yet supported. This has a broader impact than it might
    appear: not only are interface types themselves absent, but any method on a class that takes an interface as a parameter or returns an interface type is also suppressed. This means some methods on otherwise-supported classes will be missing from the bindings.
  • Callbacks: Functions that accept OCaml callbacks as arguments (beyond signals) are not yet
    supported. This limits use of many asynchronous GIO APIs and some GTK patterns.
  • Free functions: Top-level functions (not attached to a class) are not yet generated. Some
    utility APIs are therefore unavailable.
  • Non-opaque record field access: Fields of non-opaque GLib/GDK records cannot yet be read
    directly.
  • Multi-parameter signals: Only signals with zero parameters and no return value are supported; signals with complex signatures are silently skipped.
  • GLib types: most GLib types are not bound, which means that several useful APIs that use lists, byte arrays, GVariants (heavily used by DBus) are not available.

These gaps mean you can build basic GTK applications, but expect to hit walls with more advanced widget usage, asynchronous I/O, or any API that relies heavily on interfaces.

There is a ROADMAP.md that lists the rough plan to deal with much of the above.

Documentation

API reference documentation is currently deficient. Accurately generating documentation from GIR
definitions is an unsolved problem for this project, so for now the generated modules are largely
undocumented. In the meantime, the GTK 4 documentation is the best reference for understanding
what each binding corresponds to, and the examples in the repository illustrate practical usage —
in particular the calculator example, which demonstrates a non-trivial GTK 4 application.

Stability

This code is untested in production environments. The generated bindings cover a large
surface area, but test coverage is not yet comprehensive. I would caution against use in any
production or safety-sensitive context at this stage. Comments or MRs are welcome.

This code has not been tested outside of Linux environments.

Installation and Usage

Download and pin the source code for now (I’m in the process of preparing an opam release. This is taking a some time to sort through cross-platform issues, so I’ll update here with a comment when that is available).

The bindings have been generated against GTK 4.14.5 (Ubuntu 24.04). If you have an older version, it should still compile (in theory), but you will receive runtime errors on APIs not available in your version.

  1. Download the repository:GitHub - chris-armstrong/ocgtk: GTK4 bindings for OCaml · GitHub (you can use the v0.1-preview0 tag to get what I’ve mentioned here)
  2. Pin the conf-gtk4 and ocgtk packages in their respective subdirectories
    1. opam pin conf-gtk
    2. opam pin ocgtk
  3. Run opam install ocgtk

Each library is exposed at the ocamlfind level as ocgtk.<libname> - for example, add ocgtk.gtk or ocgtk.gdk to your dune file, while depending on ocgtk in your opam / dune-project file.

Source and issue tracker: GitHub - chris-armstrong/ocgtk: GTK4 bindings for OCaml · GitHub
Feedback and bug reports welcome.

13 Likes

I’ve been waiting for this! Fantastic :smiling_cat_with_heart_eyes:

I love LablGTK2 :smiling_face_with_three_hearts: and i am glad an upgrade to GTK4 is work in progress.

Will you stick to the original GTK procedural style or will you also add a LablGTK-like Object-Oriented layer (may be in the future) ?

It already has both a procedural and object oriented wrapper.

1 Like