Open-source project
ocaml-ppx/ocamlformat avatar
ocaml-ppx/ocamlformat

ocamlformat makes the formatting argument go away

Auto-formatter for OCaml code

732 stars227 forksOCamlMIT

At a glance

What is it?
ocamlformat is a code formatter for OCaml with opinionated default settings, a small set of predefined profiles, and an RPC server that editors can talk to. Adopting it means picking a profile and accepting that the formatter, not the reviewer, decides what the code looks like.
Who is it for?
Adopt ocamlformat if your team is willing to hand layout decisions to a tool and to commit the .ocamlformat file, and skip it if a project needs to preserve handcrafted layout, since the formatter rewrites comments and docstrings too. Before rolling it out, choose a profile deliberately rather than accepting the default, keep the version key in .ocamlformat in step with the release you install, and check the CHANGES.md file before moving between 0.28.1 and 0.29.0.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 15 days ago.
What is it written in?
Mainly OCaml, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Opinionated by default, configurable down to every option

The one-line description of ocamlformat in the README is more interesting than it first appears: it is a code formatter for OCaml that comes with opinionated default settings but is also fully customizable to suit your coding style.

Opinionated is the operative word. A formatter that preserved your layout would not be worth running in CI. The value of ocamlformat is that it removes layout decisions from code review entirely, and the price is that the resulting style is not necessarily the one you would have picked. The README frames the tool the same way, offering three predefined formatting configurations as profiles: default, ocamlformat and janestreet.

The three are not cosmetic labels for the same thing. A profile is a complete set of decisions, so picking janestreet means adopting that style wholesale rather than picking a few options. Users can change the profile and configure every option in their .ocamlformat configuration file, which is the escape hatch when a default does not fit.

There is also a feature that separates this from a plain pretty printer. ocamlformat can format comments, docstrings, and even code blocks in your comments. That is a real advantage in a language where documentation carries a lot of the meaning, and it is also the place where a formatter most often surprises people, because reformatting prose inside a comment changes lines a human wrote by hand.

The project is part of the OCaml Platform, described in the README as the recommended set of tools for OCaml, so it sits in the default toolchain rather than as an optional extra.

The .ocamlformat file pins both the profile and the formatter version

Configuration lives in a file called .ocamlformat in the project root, and the example in the README is two lines long.

toml
profile = default
version = 0.29.0

The profile line selects one of the predefined configurations. The version line is the more interesting one and the documentation available here does not explain what happens when the installed binary and the recorded version disagree. What it does make clear is that the formatter version is part of the project configuration rather than a property of the machine, which is the right way to handle a tool whose output can change between releases.

This matters in practice. A repository that formats in CI and a developer running a different release locally can produce different bytes for the same source. Pinning the version in a committed file is how a project keeps the two in agreement, and why the version number belongs in version control next to the profile.

The repository itself follows the practice. A .ocamlformat file sits at the top level, alongside an .ocamlformat-ignore file for exclusions and an .ocp-indent file, which is the configuration format used by the older indent-based tool. Having both present is a good hint at the history of the tool and at the migration path for projects coming from that earlier formatter.

Installing with opam and formatting a single file

The prerequisites are OCaml and opam, the OCaml package manager, and the README points to the OCaml.org installation page for the initial setup. With those in place, installation is a single opam command.

bash
opam install ocamlformat

Formatting one file is equally short.

bash
ocamlformat file.ml

The full set of configuration options is available through ocamlformat --help, and the complete user and API guides are published on OCaml.org under the ocamlformat documentation. The repository also carries doc/, and the published package set in the top level shows the project is split into several opam packages: ocamlformat.opam, ocamlformat-lib.opam, ocamlformat-rpc-lib.opam and ocamlformat-bench.opam, each with a .opam.template counterpart. The library and RPC packages are installed alongside the executable, which is what allows other OCaml tools to depend on the formatter itself rather than shelling out to it.

For a project already using dune, there is a shorter route still, described in the README as the way to make formatting easier.

dune fmt turns the formatter into a build step

If the project uses the dune build system, formatting does not need a separate command.

bash
dune fmt

That matters because of where formatting usually fails in practice. A formatter that developers have to remember to run drifts, and a formatter that is part of the build runs on every build. The Makefile in the repository shows how the project itself treats this: the fmt target runs dune build @fmt, and the test target depends on fmt before the regression tests run.

The Makefile also documents the rest of the development loop, which is useful context for anyone thinking about contributing. regtests runs dune runtest, and regtests-promote runs dune runtest --auto-promote, which is how expected outputs in the test suite are updated when the formatter's behaviour changes on purpose. Coverage is produced by running dune runtest with the bisect_ppx instrumentation and then bisect-ppx-report html. The bench target builds and runs bench/bench.exe.

The auto-promote step is the mechanism behind the version pinning in .ocamlformat. A behaviour change in a new release is accepted deliberately, the expected outputs are promoted, and the version recorded in the configuration is moved forward with it. That is a sane model, and it is also the part that generates diff noise in a large repository when a release lands.

The RPC server avoids spawning a process per keystroke

The fourth feature listed in the README is the one that matters for editor integration. ocamlformat provides an RPC server that can be used by other tools to easily format OCaml code.

The repository layout confirms this is a first-class part of the project rather than an afterthought, with separate lib-rpc/ and lib-rpc-server/ directories and a dedicated ocamlformat-rpc-lib.opam package. The Makefile builds two binaries, the formatter itself at bin/ocamlformat/ocamlformat.exe and the RPC entry point at bin/ocamlformat-rpc/main.exe.

The reason this exists is a straightforward engineering one. A tool that formats on save, or on a format-on-save hook in an editor, has to start a process, load the configuration, parse the file and write the result every time the user saves. A long-lived server holds that state between calls, so the cost per save is the formatting work rather than the process startup.

That is the real alternative in this project, and the difference is in the execution model rather than in the formatting rules. Running ocamlformat file.ml from a shell or a pre-commit hook spawns a fresh process every time, which is simple and has no daemon to manage. Pointing an editor at the RPC server keeps one process alive, which is faster in the editor and introduces a long-lived component in the development environment. The same formatting output applies either way, since both paths run the same code in lib/.

Version releases move the formatting output

The release history shows a project that moves regularly and in a way that can change results. Version 0.27.0 was published on 2024-12-02, 0.28.1 on 2025-10-24, and 0.29.0 on 2026-03-17. The last push was on 2026-10-07, and the repository is not archived.

The interesting detail is the gap between 0.27.0 and 0.28.1, almost eleven months, compared with the shorter gap between 0.28.1 and 0.29.0. Nothing in the release list says why, and the CHANGES.md file at the root of the repository is where that history lives. The README does not summarise the changes, so anyone upgrading has to read the changelog to find out whether their files will be reformatted.

That is the concrete upgrade cost for a formatter: not the install, but the diff. A new release that adjusts a layout rule rewrites every file in the repository, and in a large codebase that diff is large enough to hide a real change. The version key in .ocamlformat and the auto-promote workflow in the Makefile are the two mechanisms that make this manageable.

The project is distributed under the terms of the MIT License, with the full text in the LICENSE file. There is no restriction on commercial use or redistribution, which is what makes it usable inside a proprietary codebase without a separate agreement.

Editorial conclusion

Adopt ocamlformat if your team is willing to hand layout decisions to a tool and to commit the .ocamlformat file, and skip it if a project needs to preserve handcrafted layout, since the formatter rewrites comments and docstrings too. Before rolling it out, choose a profile deliberately rather than accepting the default, keep the version key in .ocamlformat in step with the release you install, and check the CHANGES.md file before moving between 0.28.1 and 0.29.0.

Frequently asked questions

How do I install ocamlformat?

You need OCaml and opam installed, then run opam install ocamlformat. The README points to the OCaml.org installation page for the initial setup.

What are the ocamlformat profiles and how do I choose one?

ocamlformat ships three predefined profiles: default, ocamlformat and janestreet. You select one and override individual options in the .ocamlformat configuration file in your project.

What does the version key in .ocamlformat do?

The configuration example in the README records profile = default together with version = 0.29.0, so the formatter version is pinned per project rather than depending on the machine. The README does not describe what happens when the installed binary differs from the recorded version.

Can ocamlformat format code inside comments and docstrings?

Yes. The README states that ocamlformat can format comments, docstrings, and even code blocks in your comments.

How do I use the ocamlformat RPC server?

The project ships an RPC server so other tools can format OCaml code, with the server code in lib-rpc/ and lib-rpc-server/ and its own ocamlformat-rpc-lib.opam package. The Makefile builds it as bin/ocamlformat-rpc/main.exe.

What licence is ocamlformat released under?

It is distributed under the terms of the MIT License, with the details in the LICENSE file at the root of the repository.

Official sources

  1. Issues
  2. License: MIT
  3. ocaml-ppx/ocamlformat on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ocaml-ppx-ocamlformat.svg)](https://hysenlabs.com/projects/ocaml-ppx-ocamlformat)