# How does one create a proper OCaml project?

**URL:** https://discuss.ocaml.org/t/how-does-one-create-a-proper-ocaml-project/9239
**Category:** Learning
**Tags:** ocaml, makefile, testing, dune, library
**Created:** [January 29, 2022, 2:52pm UTC](https://discuss.ocaml.org/t/how-does-one-create-a-proper-ocaml-project/9239 "2022-01-29T14:52:02Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![Nolord](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nolord/32/3542_2.png) [@Nolord](https://discuss.ocaml.org/u/Nolord)
#### Post date: [January 29, 2022, 2:52pm UTC](https://discuss.ocaml.org/t/how-does-one-create-a-proper-ocaml-project/9239/1 "2022-01-29T14:52:02Z")

</div>

How do I use files like Makefiles, dune, \_tags, .ocamlinit, and other to make a proper OCaml project?  
What do I have to do to be able to use online libraries into my projects?  
And finally, what manners should I adopt while coding ? (ie modular programming?)

I want to be able to easily run tests, compile, and setup a new project.  
Maybe already existing tools could help.

I’m on Ubuntu and I’m coding with Emacs with Tuareg installed for the moment.

---

<div class="post-metadata">

### Author: ![mro](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mro/32/2496_2.png) [@mro](https://discuss.ocaml.org/u/mro)
#### Post date: [January 29, 2022, 2:56pm UTC](https://discuss.ocaml.org/t/how-does-one-create-a-proper-ocaml-project/9239/2 "2022-01-29T14:56:45Z")

</div>

I don’t know the canonical way, but I manually create/copy files and directories like at [mro/Tagger: ♊️ Mirror of https://code.mro.name/mro/Tagger | 🐫 Add, delete and list tags of files stored in filenames. - Tagger - Codeberg.org](https://codeberg.org/mro/Tagger) – namely the mentioned `dune`, `Makefile` etc.

It’s so easy done, I didn’t research automation.

---

<div class="post-metadata">

### Author: ![Ulugbek](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ulugbek/32/1864_2.png) [@Ulugbek](https://discuss.ocaml.org/u/Ulugbek)
#### Post date: [January 29, 2022, 4:30pm UTC](https://discuss.ocaml.org/t/how-does-one-create-a-proper-ocaml-project/9239/3 "2022-01-29T16:30:20Z")

</div>

This may help:

> **[Up and Running with OCaml · OCaml Tutorials](https://v3.ocaml.org/learn/up-and-running-with-ocaml)**
>
> Help you install OCaml, the Dune build system, and support for your favourite text editor or IDE.

For project template generators: either use `dune init ...` as in the tutorial above or [GitHub - tmattio/spin: OCaml project generator.](https://github.com/tmattio/spin) (this can be installed by running `opam install spin`)

---

<div class="post-metadata">

### Author: ![lindig](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lindig/32/532_2.png) [@lindig](https://discuss.ocaml.org/u/lindig)
#### Post date: [January 29, 2022, 4:44pm UTC](https://discuss.ocaml.org/t/how-does-one-create-a-proper-ocaml-project/9239/4 "2022-01-29T16:44:11Z")

</div>

I keep [hello](https://github.com/lindig/hello) as a generic minimal OCaml project as a starting point.

---

<div class="post-metadata">

### Author: ![bluddy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/bluddy/32/104_2.png) [@bluddy](https://discuss.ocaml.org/u/bluddy)
#### Post date: [January 29, 2022, 7:24pm UTC](https://discuss.ocaml.org/t/how-does-one-create-a-proper-ocaml-project/9239/5 "2022-01-29T19:24:42Z")

</div>

Another option is [drom](https://ocamlpro.github.io/drom/sphinx/quickstart.html#creating-a-project), which is similar to `spin`, but also wraps opam and dune commands, as well as publishing to github.

---

<div class="post-metadata">

### Author: ![cdaringe](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/cdaringe/32/2419_2.png) [@cdaringe](https://discuss.ocaml.org/u/cdaringe)
#### Post date: [January 30, 2022, 3:34am UTC](https://discuss.ocaml.org/t/how-does-one-create-a-proper-ocaml-project/9239/6 "2022-01-30T03:34:59Z")

</div>

[OCaml Best Practices](https://v3.ocaml.org/learn/best-practices) =\> bootstrap

---

<div class="post-metadata">

### Author: ![Tim-ats-d](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/tim-ats-d/32/3268_2.png) [@Tim-ats-d](https://discuss.ocaml.org/u/Tim-ats-d)
#### Post date: [January 31, 2022, 10:43am UTC](https://discuss.ocaml.org/t/how-does-one-create-a-proper-ocaml-project/9239/7 "2022-01-31T10:43:15Z")

</div>

I personally use [Oskel](https://github.com/CraigFe/oskel)  
which is rather customizable.

---

<div class="post-metadata">

### Author: ![lindig](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lindig/32/532_2.png) [@lindig](https://discuss.ocaml.org/u/lindig)
#### Post date: [January 31, 2022, 11:22am UTC](https://discuss.ocaml.org/t/how-does-one-create-a-proper-ocaml-project/9239/8 "2022-01-31T11:22:40Z")

</div>

A complete project comprises of several (opinionated) files like Makefile, CI, tests and so on. That is why `dune init` is not a complete solution. A skeleton generator is convenient but it is difficult to maintain by itself. Hence why I am not too convinced by them and think a collection of generic GitHub repos is a good idea (or one repo with several branches for various use cases). There could be a command that clones and instantiates them.

---

<div class="post-metadata">

### Author: ![ifazk](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ifazk/32/836_2.png) [@ifazk](https://discuss.ocaml.org/u/ifazk)
#### Post date: [January 31, 2022, 7:51pm UTC](https://discuss.ocaml.org/t/how-does-one-create-a-proper-ocaml-project/9239/9 "2022-01-31T19:51:09Z")

</div>

> [@Nolord](#):
>
> want to be able to easily run tests

There are a few options, all of which are “proper”: running test executables with dune, dune cram tests, alcotest, dune inline tests with ppx\_inline\_tests, dune inline tests with qtest, qcheck, coverage reports with bisect\_ppx, etc.

If you want us to chime in on the pros and cons of our favourites, I would suggest starting a separate thread for testing.
