ZxCaml

OCaml frontend. Zig backend. Solana BPF.

Functional Solana, today.

ZxCaml borrows upstream OCaml's parser and type checker, throws away the OCaml runtime, and lowers a practical `.ml` subset through Core IR and ANF into deterministic BPF output through Zig.

Compiler Architecture

Keep OCaml's frontend. Own everything after Typedtree.

01

Upstream OCaml

Parsing and type checking are handled by OCaml compiler-libs, without forking the compiler.

02

Wire 1.1 to Core IR

The current bridge lowers typed OCaml into ANF-shaped Core IR with layout information.

03

Zig Pipeline

Shared lowering feeds three backends: tree-walk interpreter, native Zig codegen, and Solana BPF artifacts.

04

Demo-Ready BPF

The target path emits runtime-free `.so` programs, Anchor-compatible IDL, and artifacts exercised through Mollusk and Surfpool demo flows.

Current State

A current compiler path with clear boundaries.

ZxCaml is an active hackathon-stage compiler: P8 optimizations are implemented, real examples check, run, emit IDL, and build BPF artifacts, and the Solana path is validated through Mollusk and Surfpool demo scripts. It remains a deliberately scoped OCaml subset rather than a claim of full OCaml compatibility.

P8Compiler optimizations implemented
1.1Current frontend wire format
54+Example programs across the OCaml subset
3Interpreter, native Zig, BPF paths
223/224Zig tests passed, with one skipped
107sEnd-to-end Surfpool demo runtime

Colosseum Hackathon

Demo artifacts, scripts, and Anchor comparison in one place.

OCaml on Solana should not mean a toy VM; with ZxCaml, an ordinary `.ml` file can become a real deployable BPF program. In the demo, ZxCaml compiles `hackathon_greet.ml`, a PDA-backed greeting counter, into a `.so` and Anchor-compatible IDL, proves init plus two greet calls in Mollusk, then deploys to Surfpool and reads back real account state.

Anchor Comparison

Smaller source and BPF output for the same greeting demo.

ZxCaml source
39 lines
Anchor source
105 lines
ZxCaml BPF
6.5 KB
Anchor BPF
183.5 KB

Live Code Preview

One OCaml example, one static IDL shape.

The hackathon greeting counter is ordinary `.ml` source on the left. The right panel shows the Anchor-compatible IDL emitted for the same program, including the `instructions` array consumed by demo tooling.

examples/hackathon_greet.ml OCaml
(* hackathon: greeting counter — Colosseum demo *)

external hash_bytes : bytes -> bytes = "sol_sha256_alloc"
external log_message : string -> unit = "sol_log_"
external hackathon_greet_process : account -> account -> bytes -> int
  = "hackathon_greet_process"

let read_u8 bytes offset =
  (* Type witness for ZxCaml lowering; codegen emits the real byte read. *)
  let _ = hash_bytes bytes in
  offset - offset

let instruction_init (greeting_account : account) (maker : account) =
  (* IDL-only export: the runtime entrypoint dispatches discriminator 0 to the
     same helper below, while `omlz idl` discovers instruction_* functions as
     Anchor instructions. *)
  if greeting_account.is_writable then
    if maker.is_signer then 0 else 1
  else 1

let instruction_greet (greeting_account : account) (maker : account) =
  (* IDL-only export: discriminator 1 increments the greeting state and records
     maker on the first greet in the runtime helper. *)
  if greeting_account.is_writable then
    if maker.is_signer then 0 else 1
  else 1

let entrypoint greeting_account maker instruction_data =
  (* The greeting account is the PDA derived from ["greet", maker.key].
     The Mollusk fixture follows the repository's canonical bump-255 PDA
     pattern: tests choose a maker whose canonical PDA bump is 255, and the
     runtime helper verifies that exact bumped address. *)
  let _ = log_message "hackathon_greet: dispatch" in
  let discriminator = read_u8 instruction_data 0 in
  if discriminator = 0 then
    hackathon_greet_process greeting_account maker instruction_data
  else if discriminator = 1 then
    hackathon_greet_process greeting_account maker instruction_data
  else 1
out/hackathon_greet.json IDL JSON
{
  "address": "11111111111111111111111111111111",
  "metadata": {
    "name": "hackathon_greet",
    "version": "0.1.0",
    "spec": "0.1.0"
  },
  "instructions": [
    {
      "name": "init",
      "discriminator": [220, 59, 207, 236, 108, 250, 47, 100],
      "accounts": [
        { "name": "greeting_account", "writable": true, "signer": false },
        { "name": "maker", "writable": false, "signer": true }
      ],
      "args": []
    },
    {
      "name": "greet",
      "discriminator": [203, 194, 3, 150, 228, 58, 181, 62],
      "accounts": [
        { "name": "greeting_account", "writable": true, "signer": false },
        { "name": "maker", "writable": false, "signer": true }
      ],
      "args": []
    },
    {
      "name": "entrypoint",
      "discriminator": [237, 127, 171, 8, 17, 8, 23, 233],
      "accounts": [],
      "args": [
        { "name": "greeting_account", "type": "i64" },
        { "name": "maker", "type": "i64" },
        { "name": "instruction_data", "type": "bytes" }
      ]
    }
  ],
  "accounts": [],
  "types": [],
  "events": [],
  "errors": [],
  "constants": []
}

Colosseum Frontier 2026

Built for developers exploring safer Solana programming models.

ZxCaml is being shaped as an early developer tool for the Frontier hackathon: a functional, type-driven route for Solana programs that need deterministic output without carrying a garbage-collected runtime.

Frontier Hackathon