Building Mendix Pluggable Widgets with Gleam
Mendix is an enterprise low-code platform, and Pluggable Widgets are custom React components you drop into it. Normally TypeScript + JSX, but I wanted to try pure Gleam
So I made glendix, a Hex package with FFI bindings for React 19 + the Mendix runtime API.
What's in it:
- 115 HTML tags, 61 SVG elements, 117 HTML attributes, 98 SVG attributes
- 249 event handlers/accessors, 16 event types (capture phase included)
- All 42 React 19 hooks — useActionState, useFormStatus, useOptimistic, use, etc.
- 14 Mendix type modules — EditableValue, ActionValue, ListValue (paging/sort/filter), Big.js, Date, and more
- External component bindings — write a
bindings.json, FFI is auto-generated..mpkwidgets supported too - CLI tools via
gleam run -m glendix/<cmd>— install, dev, build, start, release, lint
Here's what a widget looks like:
import glendix/mendix
import glendix/react.{type JsProps, type ReactElement}
import glendix/react/attribute
import glendix/react/event
import glendix/react/hook
import glendix/react/html
pub fn widget(props: JsProps) -> ReactElement {
let name = mendix.get_string_prop(props, "sampleText")
let #(count, set_count) = hook.use_state(0)
html.div([attribute.class("my-widget")], [
html.h2_([react.text("Hello " <> name)]),
html.button([event.on_click(fn(_) { set_count(count + 1) })], [
react.text("Click me"),
]),
])
}
All JS types are opaque, undefined/null converts to Option at the FFI boundary. attribute.none() for conditional attrs, multiple attribute.class() calls auto-merge.
Scaffolding: npx create-mendix-widget-gleam MyWidget
Hex: https://hexdocs.pm/glendix/
GitHub: https://github.com/GG-O-BP/glendix
Example: https://github.com/GG-O-BP/MendixWidgetGleam
Feedback welcome, especially on API design!