Managing Dependencies With opam

Installing Existing Dependencies

We recommend installing a project's dependencies in a local opam switch to sandbox your development environment.

If you're using opam 2.0.X, you can do this with:

# if you need external system dependencies
opam pin add -n .
opam depext -i <packages>
opam install . --deps-only --with-test --with-doc

If you use opam 2.1.X, it will install the system dependencies automatically, so you can run:

opam install . --deps-only --with-test --with-doc

Now, if for some reason you prefer to install your dependencies in a global switch, you can run:

opam switch set <switch_name>
opam install . --deps-only --with-test --with-doc

Once the dependencies have been installed successfully, and assuming the project uses Dune as the build system, you can compile it with:

opam exec -- dune build

Or if you set your environment with eval $(opam env):

dune build

Adding Dependencies From the opam Repository

To avoid duplicating the project configuration into multiple files, Dune allows you to generate the project's *.opam file from the package definitions in dune-project when adding the (generate_opam_files true) stanza.

However, opam remains a central piece of the ecosystem, and it's very likely that you will have to work with *.opam files at some point, so we don't take a stance on whether you should specify your dependencies in the *.opam file or in dune-project.

Adding a Dependency to Your dune-project File

If the project generates the opam file from the dune-project (you can tell by the line # This file is generated by dune, edit dune-project instead at the top of the *.opam file), you can add your dependencies in the dune-project in the appropriate package stanza. It should look like this:

(package
 (name demo)
 (synopsis "A short, but powerful statement about your project")
 (description "An complete and exhaustive description everything your project does.")
 (depends
  (ocaml
   (>= 4.08.0))
  dune
  (alcotest :with-test)
  (odoc :with-doc)))

Once you have added your dependency, you can build your project with dune build which will regenerate the *.opam files.

Adding a Dependency to Your .opam File

If the *.opam files are not generated, you can add the dependencies in them directly in the depends field. It should look like this:

opam-version: "2.0"
synopsis: "A short, but powerful statement about your project"
description: "An complete and exhaustive description everything your project does."
depends: [
  "ocaml" {>= "4.08.0"}
  "dune"
  "alcotest" {with-test}
  "odoc" {with-doc}
]
build: [
  ["dune" "subst"] {pinned}
  [
    "dune"
    "build"
    "-p"
    name
    "-j"
    jobs
    "@install"
    "@runtest" {with-test}
    "@doc" {with-doc}
  ]
]

Either way, once you have added your dependency in the appropriate file, you can run opam install . --deps-only to update your current switch dependencies.

Installing a Dependency in Your Switch

Installing a package from the opam repository to your active switch, you can run

opam install <package-name>

to get the latest version of the package.

If you want to install a specific version of the package, use

opam install <package-name>.<package-version>

instead.

Adding Dependencies From a Git Repository

Sometimes, you may want to install a package directly from a Git repository, e.g., when it is not available on the opam repository or when you want to use an unreleased version.

Adding a Git Dependency to a dune-project File

In OCaml projects that use Dune for building and opam for package management, you can specify Git dependencies using a combination of dune-project and .opam.template files.

This approach is particularly useful when you want to keep the Dune and opam configurations in sync, especially when dealing with external dependencies from Git repositories.

If your project does not have a file matching the name of your project's .opam file, but with the file extension .opam.template, you have to create it.

For example, if your project's opam file is my_project.opam, create my_project.opam.template and use pin-depends to tell opam to install a package from a Git repository.

pin-depends: [
  ["<package-name>.dev" "git+https://<repository-url>#<branch-or-commit>"]
]

Next, regenerate the .opam file of your project by running

opam exec -- dune build

Then, run

opam install . --deps-only

to install the new dependency you added.

Adding a Git Dependency to Your .opam File

To open your opam file, locate the opam file for your OCaml project. This file defines the package's dependencies and other metadata.

Add the pin-depends field in the opam file if it doesn't exist. Inside this field, you specify the package and the URL from which it should be fetched. For example:

pin-depends: [
  ["<package-name>.dev" "git+https://<repository-url>#<branch-or-commit>"]
]

Finally, use opam install to install the dependencies, including the one specified in the pin-depends field.

opam install . --deps-only

Installing a Git Dependency in Your Switch

You can install a package in your active switch directly from a Git URL:

opam pin add <package-name> <git-url>#<branch-or-commit>

Dealing With Development-Only Dependencies

Opam does not have a notion of development dependencies. Instead, each dependency can be either:

  • A normal dependency (used at runtime)
  • A build dependency (used to build the project)
  • A test dependency (used to test the project)
  • A documentation dependency (used to generate the documentation)

When adding a new dependency, as seen in the "Update Dependencies" workflow, you can add a flag to your dependency.

For dune-project, it looks like this:

(alcotest :with-test)

And for the *.opam file, it looks like:

"alcotest" {with-test}

The available flags for each dependencies are:

  • Normal: no flag
  • Build: build
  • Test: with-test
  • Documentation: with-doc

See opam documentation for more details on the opam syntax.

Help Improve Our Documentation

All OCaml docs are open source. See something that's wrong or unclear? Submit a pull request.