[ANN] ppx_deriving_melange 0.1.0 - eq, ord, show, map, iter derivers for Melange

Hi everyone,

I’m happy to announce the first release of ppx_deriving_melange, a Melange-compatible subset of ppx_deriving: GitHub - ahrefs/ppx_deriving_melange: Melange-compatible deriving plugins for OCaml · GitHub

Why

The original ppx_deriving can’t support Melange: it predates dune’s Melange integration — it is distributed through findlib META files, and its generated code depends on a runtime library that isn’t built in Melange mode. Melange can only link libraries that dune builds for it, so common patterns like [@@deriving eq, show] were off the table when writing frontend OCaml.

ppx_deriving_melange fills that gap: same derivers, same naming conventions and attributes, implemented on ppxlib and tested against Melange — and its generated code is self-contained, so nothing extra needs to link into your bundle.

A key use case is universal code — libraries compiled both natively and to JavaScript. Put your shared types in a library with (modes :standard melange), derive once, and the exact same equal/compare/show functions run on the server and in the browser. (This is how the project tests itself: one test-case library exercised by OUnit natively and by node on the Melange side.)

What you get


type user = {

  name : string;

  roles : string list;

}

[@@deriving eq, ord, show]



(* generates:

   val equal_user : user -> user -> bool

   val compare_user : user -> user -> int

   val pp_user : Format.formatter -> user -> unit

   val show_user : user -> string *)

Supported derivers in 0.1.0: eq, iter, map, ord, and show, following the native ppx_deriving conventions — including the equal, compare, and printer attribute overrides, the with_path option for show, tuples, records, (polymorphic) variants, options, lists, arrays, results, type parameters, and recursive type groups. The README documents the exact supported scope of each deriver.

Two design points worth calling out:

  • Self-contained generated code. There is no runtime library: the generated functions only use the stdlib, so the ppx is a build-time dependency only.

  • Bundle-size-aware show. Melange compiles Stdlib.Format into a lot of JavaScript, so show builds its string directly and only falls back to Format where the type requires it (custom printers, etc.). Code that only calls show doesn’t pull Format into your bundle; pp stays fully Format-based and native-compatible.

What’s not there (yet)

Some ppx_deriving derivers aren’t implemented yet (enum, fold, make, …), and a few type shapes are out of scope for now (ref, lazy_t, nativeint, functor-applied types). If you need one of these — or hit anything that behaves differently from native ppx_deriving — please open an issue; that’s exactly the feedback that will drive what gets built next.

Using it


opam install ppx_deriving_melange


(library

 (name my_frontend_lib)

 (modes melange)

 (preprocess

  (pps ppx_deriving_melange)))

Thanks to the ppx_deriving authors — this project follows their design and behavior closely, and includes their license attribution — and to davesnx for reviews and encouragement along the way.

Feedback, issues, and deriver requests very welcome!

3 Likes