Syaiful Bahri

How to Embed Static Files in OCaml

I love how Go lets me embed static files into a binary. This solves the problem of bundling HTML templates, CSS, JavaScript, and even SQL migration files — no need to ship separate files and folders.

Recently I was working on a project in OCaml and I wanted to do the same thing. I found a library called ocaml crunch. This library does exactly what I wanted — it allows converting a filesystem into a static OCaml module.

Here is how to use it. Suppose we have the following directory structure:

- assets/
  - data/ <-- we want to embed this directory
    - file1.txt
    - file2.txt
  - dune

In your assets/dune file, you can add the following lines:

(rule
 (deps
  (source_tree data))
 (targets assets.ml)
 (action
  (run ocaml-crunch -m plain -o %{targets} ./data)))

This tells dune to track the data directory and run ocaml-crunch, which will generate assets.ml for us.

After that rule, we can add the library stanza as usual:

(rule
 (deps
  (source_tree data))
 (targets assets.ml)
 (action
  (run ocaml-crunch -m plain -o %{targets} ./data)))

(library
 (name project_assets)
 (public_name project.assets))

The generated module has the following signature:

sig
  val file_list : string list
  val read : string -> string option
  val hash : string -> string option
  val size : string -> int option
end