Help us improve
Share bugs, ideas, or general feedback.
From ocaml-dev
Migrates OCaml projects from ocamlbuild/topkg to dune by converting _tags, .mllib, pkg.ml files, handling libraries/tests, and updating opam. Use for build system migrations.
npx claudepluginhub avsm/ocaml-claude-marketplace --plugin ocaml-devHow this skill is triggered — by the user, by Claude, or both
Slash command
/ocaml-dev:dune-migrationThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Invoke this skill when:
Guides OCaml development with opam for packages, dune for builds/tests, merlin for editor support, ocamlformat for formatting. Includes project setup workflows and examples.
Provides OCaml project setup standards for dune files, .mli interfaces, ocamlformat, logging, licenses, CI, and structure. Use for new libraries, opam releases, or reviews.
Generates migration plans and automated scripts for transitioning codebases between frameworks, languages, versions, or platforms with risk assessment and rollback strategies.
Share bugs, ideas, or general feedback.
Invoke this skill when:
Read these files to understand the project:
_tags - ocamlbuild compilation flags and package dependenciespkg/pkg.ml - topkg package descriptionpkg/META - findlib metadata*.mllib files - module lists for librariesopam - package dependencies(lang dune 3.20)
(name <package-name>)
(generate_opam_files true)
For each library (from .mllib files):
(library
(name <library_name>)
(public_name <package.subname>)
(libraries <dependencies>))
For optional libraries (from pkg/pkg.ml):
(library
(name <library_name>)
(public_name <package.subname>)
(optional)
(libraries <dependencies>))
Files like *_top_init.ml shouldn't be compiled as modules:
(library
(name lib_name)
(modules lib_module) ; Explicitly list modules
(libraries deps))
(install
(package pkg)
(section lib)
(files lib_top_init.ml))
If the original code triggers warnings:
(library
(name lib)
(flags (:standard -w -27)))
Common warnings to suppress in vendored code:
-w -27 - unused variable(test
(name test_name)
(libraries lib_name alcotest))
For optional tests:
(executable
(name test_optional)
(modules test_optional)
(optional)
(libraries lib some_optional_lib))
opam to <package>.opamdepends: [
"ocaml" {>= "4.14.0"}
"dune" {>= "3.0"}
]
build: [
["dune" "subst"] {dev}
["dune" "build" "-p" name "-j" jobs]
["dune" "runtest" "-p" name "-j" jobs] {with-test}
["dune" "build" "@doc" "-p" name "-j" jobs] {with-doc}
]
If there's a doc/ directory:
(documentation
(package <package-name>))
Files to delete:
_tags.merlinpkg/pkg.mlpkg/META*.mllib files*.itarget filespkg/ directory| ocamlbuild | dune |
|---|---|
_tags: package(foo) | (libraries foo) |
_tags: thread | (libraries threads) |
foo.mllib with Foo | (library (name foo) (modules foo)) |
pkg/pkg.ml: Pkg.mllib ~cond:x | (library ... (optional)) |
pkg/META | Auto-generated by dune |
opam | <package>.opam |
Use (optional) on the library stanza.
Add (flags (:standard -w -27)).
Use (modules ...) to explicitly list modules.
Exclude from library with (modules ...) and use (install ...).
After migration:
dune build @check # Verify syntax
dune build # Build project
dune runtest # Run tests
dune build @doc # Build docs