npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bs-ocaml-protoc

v1.0.2

Published

A Protocol Buffers compiler for OCaml

Readme

ocaml-protoc

A protobuf compiler for OCaml.

Introduction

ocaml-protoc compiles protobuf message files into OCaml modules. Each message/enum/oneof protobuf type has a corresponding OCaml type along with the following functions:

  • encode_<type> : encode the generated type to bytes following protobuf specification
  • decode_<type> : decode the generated type from bytes following protobuf specification
  • default_<type> : default value honoring protobuf default attributes or protobuf version 3 default rules
  • pp_<type> : pretty print of the OCaml type

The compiler relies on a runtime library pbrt which is itself implemented using the same runtime library as ppx_deriving_protobuf for low level encoding/decoding.

OCaml users have now 2 complementary options to choose for protobuf serialization:

  • If your application is mainly OCaml then ppx_deriving_protobuf is usually the best tool. You can leverage the OCaml type system as a schema definition and minimum setup is required to support serialization.
  • If your application is using multiple languages and you are leveraging Protobuf as a language-independent data specification, then ocaml-protoc is likely a more suitable option. ocaml-protoc guarantees that the generated OCaml types conform to the protobuf specifications.

A simple example

Let's take a similar example as the google one:

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;
  repeated string phone = 4;
}

The following OCaml code will get generated after running ocaml-protoc -ml_out ./ example.proto

(** example01.proto Generated Types and Encoding *)

(** {2 Types} *)

type person = {
  name : string;
  id : int32;
  email : string option;
  phone : string list;
}


(** {2 Default values} *)

val default_person : 
  ?name:string ->
  ?id:int32 ->
  ?email:string option ->
  ?phone:string list ->
  unit ->
  person
(** [default_person ()] is the default value for type [person] *)


(** {2 Protobuf Decoding} *)

val decode_person : Pbrt.Decoder.t -> person
(** [decode_person decoder] decodes a [person] value from [decoder] *)


(** {2 Protobuf Encoding} *)

val encode_person : person -> Pbrt.Encoder.t -> unit
(** [encode_person v encoder] encodes [v] with the given [encoder] *)


(** {2 Formatters} *)

val pp_person : Format.formatter -> person -> unit 
(** [pp_person v] formats v] *)

You can then use this OCaml module in your application to populate, serialize, and retrieve person protocol buffer messages. For example:

let () =

  (* Create OCaml value of generated type *) 
  let person = Example_pb.({ 
    name = "John Doe"; 
    id = 1234l;
    email = Some "[email protected]"; 
    phone = ["123-456-7890"];
  }) in 
  
  (* Create a Protobuf encoder and encode value *)
  let encoder = Pbrt.Encoder.create () in 
  Example_pb.encode_person person encoder; 

  (* Output the protobuf message to a file *) 
  let oc = open_out "myfile" in 
  output_bytes oc (Pbrt.Encoder.to_bytes encoder);
  close_out oc

Then later on you can read your message back in:

let () = 
  (* Read bytes from the file *) 
  let bytes = 
    let ic = open_in "myfile" in 
    let len = in_channel_length ic in 
    let bytes = Bytes.create len in 
    really_input ic bytes 0 len; 
    close_in ic; 
    bytes 
  in 
  
  (* Decode the person and Pretty-print it *)
  let person = Example_pb.decode_person (Pbrt.Decoder.of_bytes bytes) in
  Format.fprintf Format.std_formatter "%a" Example_pb.pp_person person

OCaml users will immediately point to the use of int32 type in the generated code which might not be the most convenient choice. One can modify this behavior using custom extensions.

Build-Install

Prerequesite

ocaml-protoc depends on :

  • the OCaml compiler distribution (byte code/native compiler and ocamlbuild).
  • ppx_deriving_protobuf for the generated code runtime.

Intall from OPAM

opam install ocaml-protoc

Install from source with ocamlfind

mkdir -p tmp/bin
export PREFIX=`pwd`/tmp
make install

Build your program

Here are the steps to build the example above where the source are in src/examples/. We now assume that $PREFIX/bin is in your path.

# Generate the OCaml protobuf module 
ocaml-protoc -ml_out ./ example01.proto

When using findlib:

ocamlfind ocamlopt -linkpkg -package ocaml-protoc \
  -o example01 \
  example01_pb.mli example01_pb.ml example01.ml

You can now run the example

./example01

Protobuf <-> OCaml mapping

see here.

Compiler Internals

see here

Protobuf Extensions

see here

Benchmarking

see here