VSCode Editor Setup

I’m just getting started with OCaml development, using VSCode as a primary editor. I’m using the ocamllabs.ocaml-platform extension and it’s working quite well so far, but I have a few questions.

I’m aware that Merlin provides all of the nice IDE-like features, but I think I’m missing some sort of link between my Dune and Merlin configurations. Specifically, I don’t know of a way to make Merlin aware of any changes in my project’s modules until I build them with something like:

ocamlbuild src/foo.cmi

and Merlin sees the changes in my _build directory. So if I change the type of some function in one module and update a function to accept that new type in a different module, Merlin will display an error in the editor indicating that it’s not aware of that new type until I build the other module. And even when Merlin complains like that, I can dune build just fine.

I know that this is how Merlin works and I don’t think anything is wrong with it, but it seems like the cmi files that Merlin gets its information from should have some way to be automatically generated/updated? Am I missing some piece of a more common, better workflow? I’ve looked for sources online describing a better workflow with this but haven’t had any luck.

Would very much appreciate any pointers or ideas that might help me smooth this out!

I usually just run dune build -w (watch mode) in the integrated terminal which updates the generated files as I work on a project.


If you’re starting a new project, don’t use ocamlbuild, use dune. If you’re working on an existing project, in the long run (even in the medium run) it’s best to port it away from ocamlbuild to dune.


Okay cool, I didn’t now about dune build -w! Now I’m using that, however I’m finding that Merlin is still not picking up on any of Dune’s build results. For example, my project is in a state where Dune is reporting a type error, but Merlin still thinks the types are lining up and therefore the text-editor is not showing such an error. Here’s a screenshot that I hope demonstrates it:

It seems like I’m messing something up and Merlin isn’t following along with what Dune is seeing… any ideas what I could check? Thanks for the help!

Try reloading the VSCode window. Sometimes the editor plugin needs a kickstart to catch up to the project.

The editor plugin still reports no errors after a reload, and I think it’s because I have Merlin looking at different build results than Dune. Dune is building and putting results in ./_build/default/src while my Merlin .merlin config has:

S src
B _build/src

So, should Merlin be looking in ./_build/default/src? Because when I change my Merlin config to look there, it no longer recognizes any of my modules and I get a lot of errors. Happy to provide more info on my configuration if necessary, thank you for the help!

We don’t configure Merlin directly, the editor plugin does that. Try deleting all .merlin files in the project and starting from a fresh build, reloading the window, etc.

Ah okay! I’ve gotten rid of my Merlin configuration and rebuilt the project, now the editor plugin is giving me this error, even though I’ve ran dune build and have dune build -w going:


To clarify, the sequence of steps is:

  1. Delete any existing .merlin files in the project
  2. Run dune build (it must succeed with no errors)
  3. Reload VSCode window

It should now recognize and load the project and enable the editor support features.

For some reason, after executing those steps exactly, it is still giving me the Project isn't built error, along with Unbound module errors. I am using an opam switch for the project, so my dune files are as follows:

  • dune-workspace
(lang dune 2.8)
  (name default)
  (switch /path/to/my/project)))

(Where the path is the actual path to my project directory)

  • src/dune
 (name lesson2)
 (libraries core yojson))

Does that all seem correct to you? Thank you, I really appreciate the help.

Did the build actually generate .merlin files like it was supposed to? In the docs there is a (merlin) field which apparently tells dune to use this context for merlin. That kinda sounds like, without this field being present in the context, dune won’t generate .merlin files.

If I were you I would ask if a dune-context file is strictly necessary for the project. Is it a very complex project which needs multiple contexts? Normally dune projects can start out pretty simple, with just a dune file … maybe a dune-project file at most.


Adding the (merlin) field to the dune-workspace file worked! The reason I introduced a dune-workspace file to the project was because I was using an opam switch, which was installing the project dependencies in the project’s _opam directory. Dune was still looking for packages in the global opam package database, so I added the workspace file to make it use the local packages. In hindsight, it seems like a switch wasn’t really necessary, I just wasn’t sure how opam would handle multiple versions of the same packages being installed.

1 Like

Ah, OK. You’re using a local opam switch. That’s probably a good idea for having a sandboxed build. I just didn’t realize it would interact with dune like that.

1 Like