What's your setup for OCaml development?

You might be able to rebind the Tab key in VSCode to run ocp-indent, e.g. I haven’t tried :slight_smile:

Vim 8 + Merlin. It’s perfect.

It’s curious not one person mentioned Atom. It’s great if you are a terminal person. We’re at it all the time and all. But I think I’ll never think of vim-like editors as an IDE. I simply don’t believe the vibe “you are only truly good if you live in a terminal”.

Atom is one of the most intuitive, configurable, and productive tools to work with OCaml you can find today. Compared to VSCode, I miss the mouse-hover tooltips showing type signatures, but not much else. And it is certainly great for automation. I’m crazy fast with it. Three are a few packages and tweaks needed to make OCaml like workflow smooth, but usually exploring the choices pays off.

1 Like

It’s curious not one person mentioned Atom.

Atom was a really interesting idea, and I wanted it to be good, but it’s just too memory intensive and bloated. I have had trouble using it for anything other than tests. It’s bad enough having to run electron apps like Slack in my environment — if you try using Atom on a machine without insane amounts of memory you start paging, and the amount of CPU needed to do anything beyond the simplest tasks is crazy. JavaScript simply isn’t a reasonably performing implementation language for large programs, and that’s ignoring its flaws as a language.

Emacs is not a “terminal” editor, and vim isn’t these days either. Both have quite reasonable GUI modes. Both are fully programable environments, and both are clearly IDEs if they’re set to behave that way.

If you have Tuareg and Merlin loaded, Emacs does pretty much anything that any other OCaml environment can, and of course it’s also still Emacs so it does all the things Emacs can do. (I’m not a vim user but I fully respect people who are, there’s nothing wrong with vim.)

1 Like

@perry, I understand your opinion, and I’m well aware of Atom’s performance problems. And still think it’s worthy. For my needs working with OCaml, Atom is not only a viable solution, it’s pretty much unmatched. I like the idea that we can have this conversation. We have options.

I disagree with the idea that’s something really bad about building an IDE with JS. The problem is not the evolution of web-apps, but the lack of interest in building native applications as good as the web-based. I would rather keep and tweak the intuitive interfaces, and focus on coding than having to figure out how to do multi-line editing or working with multiple projects on the terminal.

The problem is not the evolution of web-apps, but the lack of interest in building native applications as good as the web-based.

That’s not true. I’d love to build native applications but these days the GUI bindings for everything but web apps seem to be rotting away. If there was a set of OCaml bindings for the native GUI widgets on macOS for example I wouldn’t even think about web apps on the desktop. I think the biggest problem is that everyone is being pushed in that direction, and not that people are all choosing it of their own free will. But that’s another story and has little to do with development environments I’m afraid.

I would rather keep and tweak the intuitive interfaces, and focus on coding than having to figure out how to do multi-line editing or working with multiple projects on the terminal.

Emacs and Vim aren’t terminal based. If you want to open things in the terminal you can, but they’re GUI editors just like Atom is. Emacs has an extension language (elisp, not javascript) and huge suites of applications written for it. Vim has its own extension language (which I have no experience with.)

I’ve found Visual Studio Code (which is essentially unrelated to Visual Studio; more like Microsoft’s Atom, open-source and cross platform) to be quite excellent, especially for beginners. Easy to set up for OCaml, and works very smoothly. I also hear it performs better than Atom, but I haven’t done enough to know myself.

That said, I still use Emacs, Tuareg and Merlin for real work.


Same problem, didn’t solve it yet.

1 Like

I’m also seconding VSCode with vscode-reasonml extension (search “OCaml and Reason IDE” on the extensions tab). It’s nice. I’m also using Spacemacs with its OCaml layer interchangeably with VSCode. Setting up either VSCode or Spacemacs are very low friction to get a decent dev environment easily.

1 Like

Any chance to see your Emacs setup (the only OCaml part eventually) somewhere?

Thank you.

I actually use Atom (with some community packages, especially for merlin). Opening multiple windows seems hurt memory, but otherwise it’s fine (on my 8G RAM machine). I experienced large memory usage (gigabytes) by merlin. Does anyone have similar experience?

My own OCaml setup in Emacs was taken pretty cleanly from the setup described in “Real World OCaml” plus various install messages when using opam to install the packages. Nothing much special.

For those who want an emacs setup, I highly recommend using opam-user-setup. It will setup everything you need in emacs using the available tools very easily, including graceful handling of switches, merlin, and the various other utilities.


Just to add another +1 for emacs, tuareg, merlin.

Adding to this, it also works wonderfully for vim/neovim

Since it hasn’t been mentioned so far, let me also add annot to this list of tools.

Annot is a small and fast tool that just lookup types in ocaml compiler produced .annot files. It’s very easy to integrate with vi and emacs and is very lightweight.
The value of autocompletion, colorization, autoformatting may be debatable, but when programming with a language like OCaml that can infer quite complex types from far away, being able to see the actual type of any expression is very helpful when trying to figure out an error message. Annot does only this and does it well.


If you have Vim8 or Neovim it is worth trying out deoplete-ocaml: it is an asynchronous completion plugin (does not block typing) using merlin that can also show the ocamldoc during completion.
My full setup can be seen in my dotfiles, but to summarize:
When in Emacs I use Spacemacs with the ocaml layer.
When in Neovim:

  • ALE for seeing warnings/errors from merlin
  • Denite for fuzzy filename search (“Ctrl-P” like), git grep output viewing
  • deoplete+deoplete-ocaml for completion and ocamldoc viewing
  • neoformat with ocp-indent (and experimenting with ocamlformat)
  • lightline+vim-fugitive for status line, LargeFile for log files, gruvbox for colorscheme
  • some custom keymappings and conditionals in .vimrc to disable features that are not available (e.g. don’t load merlin if there is no python3, use 24-bit RGB colours when available, use ripgrep only if available etc.)

In my terminal I also use:

  • tig for exploring git history
  • tmux for managing remote sessions, it also support passing through 24-bit RGB colours, so a terminal Vim looks almost exactly the same as the GUI Vim
  • Z shell
  • ripgrep for searching
  • git with diff-highlight, histogram diff algorithm, diff3 conflict style
  • ssh with ControlMaster multiplexing
  • Source Code Pro font (OTF), with xfce4-terminal or mate-terminal emulator

I was somewhat undecided between Vim8 and Neovim (all of the above plugins work with a recent Vim 8 too, if you install some compatibility plugins): what finally made me switch to Neovim was that it is available in CentOS 7 (via EPEL), which means I can use my usual setup for remote work too.
Visual Studio Code is good too, but its Vim emulation is somewhat slow.


Try the deprecated vscode-ocaml, IIRC it integrated better with ocp-indent, the new plugin (vscode-reasonml) could only indent whole files.


Yup, the best environment. I use Aquamacs on OS X, and the stock GNU emacs on Linux. Both are great for OCaml programming when the extensions are installed.

When I typing OCaml, VScode could not indent automatically, with my config as follows:

    "reason.path.ocamlmerlin": "/Users/taki/.opam/4.05.0/bin/ocamlmerlin",
    "editor.formatOnSave": true,
    "editor.formatOnType": true,
    "reason.diagnostics.tools": [