Packaging, Style & Best Practices
46.1 Publishing to opam
Fill in dune-project metadata; dune build generates *.opam.
Tag a release: git tag 1.0.0 && git push --tags.
Use dune-release: dune-release tag && dune-release distrib && dune-release publish && dune-release opam pkg && dune-release opam submit.
A PR is opened against ocaml/opam-repository; CI checks it across platforms.
46.2 Formatting with ocamlformat
dune fmt formats the whole project. Commit the config so the team shares one style.
profile = default
version = 0.27.0
margin = 9046.3 Naming conventions
values, functions Not_found, Some modules, functors String_map, Make UPPER or S ORDERED, S main type of a module
46.4 Idioms & best practices
Make illegal states unrepresentable with variants.
One main type t per module, functions take t first (or last for piping — be consistent).
Write .mli files; keep types abstract unless needed.
Prefer option/result over exceptions in public APIs; name raising variants _exn (find_exn).
Avoid catch-all _ patterns on your own variants so the compiler flags new cases.
Turn warnings into errors in dev; keep code warning-free.
Don't use open at top level except for well-known "prelude" modules.
**Use Fun.protect / with_* functions** for resources.
Avoid polymorphic equality on abstract types — provide equal.
Keep mutation local and hidden behind pure interfaces.
Use labeled arguments when two arguments have the same type (~src ~dst).
Document with odoc, test with expect tests and QCheck.
46.5 Common warnings to know
missing record fields in pattern unused match case unused for-loop index open shadows identifier unused record field missing .mli
46.6 Alternative standard libraries
Base / Core / Core_unix (Jane Street) — comprehensive, consistent, labeled APIs.
Containers — extends stdlib compatibly (CCList, CCHashtbl, ...).
Batteries — older extended stdlib.
Stdlib has grown a lot; for many projects it's sufficient.
open Core
let () =
[1; 2; 3]
|> List.map ~f:(fun x -> x * 2)
|> List.fold ~init:0 ~f:( + )
|> printf "%d\n"46.7 Key libraries by domain
menhir, angstrom, sedlex (Unicode lexing), mparser owl, lacaml, zarith (bignums), gsl mirage-crypto, digestif, cryptokit, ocaml-tls containers, iter, saturn (lock-free), psq, lru alcotest, qcheck, ppx_expect, crowbar (fuzzing), mdx (doc tests) lablgtk3, bogue, raylib-ocaml, tsdl ptime, timedesc, calendar uutf, uucp, uunf, uuseg