diff --git a/gnu/packages/ocaml.scm b/gnu/packages/ocaml.scm
index c448e64bc7..eccc870c08 100644
--- a/gnu/packages/ocaml.scm
+++ b/gnu/packages/ocaml.scm
@@ -780,7 +780,7 @@ (define-public ocaml-down
        ,#~(list "build" "--lib-dir"
                 (string-append #$output "/lib/ocaml/site-lib"))))
     (native-inputs
-     (list ocaml-findlib ocamlbuild ocaml-topkg opam))
+     (list ocaml-findlib ocamlbuild ocaml-topkg opam-installer))
     (home-page "https://erratique.ch/software/down")
     (synopsis "OCaml toplevel (REPL) upgrade")
     (description "Down is an unintrusive user experience upgrade for the
@@ -846,9 +846,9 @@ (define-public ocaml-opam-file-format
     ;; With static-linking exception
     (license license:lgpl2.1+)))
 
-(define-public opam
+(define ocaml-opam-core
   (package
-    (name "opam")
+    (name "ocaml-opam-core")
     (version "2.1.3")
     (source (origin
               (method git-fetch)
@@ -860,32 +860,151 @@ (define-public opam
                (base32
                 "1mw535zsw7xlvpgwnk1dan76z3f7lh5imlg0s6kdyhfg0iqisjd7"))))
     (build-system dune-build-system)
+    (arguments `(#:package "opam-core"
+                 ;; tests are run with the opam package
+                 #:tests? #f
+                 #:phases
+                 (modify-phases %standard-phases
+                   (add-before 'build 'pre-build
+                     (lambda* (#:key inputs make-flags #:allow-other-keys)
+                       (let ((bash (assoc-ref inputs "bash"))
+                             (bwrap (search-input-file inputs "/bin/bwrap")))
+                         (substitute* "src/core/opamSystem.ml"
+                           (("\"/bin/sh\"")
+                            (string-append "\"" bash "/bin/sh\""))
+                           (("getconf")
+                            (which "getconf")))))))))
+    (propagated-inputs
+     (list ocaml-graph
+           ocaml-re
+           ocaml-cppo))
+    (inputs (list bubblewrap))
+    (home-page "https://opam.ocamlpro.com/")
+    (synopsis "Package manager for OCaml")
+    (description
+     "OPAM is a tool to manage OCaml packages.  It supports multiple
+simultaneous compiler installations, flexible package constraints, and a
+Git-friendly development workflow.")
+    ;; The 'LICENSE' file waives some requirements compared to LGPLv3.
+    (license license:lgpl3)))
+
+(define ocaml-opam-format
+  (package
+    (inherit ocaml-opam-core)
+    (name "ocaml-opam-format")
+    (inputs '())
+    (propagated-inputs (list ocaml-opam-core
+                             ocaml-opam-file-format
+                             ocaml-re))
+    (arguments `(#:package "opam-format"
+                 ;; tests are run with the opam package
+                 #:tests? #f
+                 #:phases %standard-phases))))
+
+(define-public opam-installer
+  (package
+    (inherit ocaml-opam-core)
+    (name "opam-installer")
+    (native-inputs (list ocaml-opam-format
+                         ocaml-cmdliner))
+    (inputs '())
+    (propagated-inputs '())
+    (arguments `(#:package "opam-installer"
+                 ;; requires all of opam
+                 #:tests? #f))
+    (synopsis "Tool for installing OCaml packages")
+    (description "@var{opam-installer} is a tool for installing OCaml packages
+based on @code{.install} files defined by the OPAM package manager.  It is
+useful for installing OCaml packages without requiring the entirety of
+OPAM.")
+    (properties
+     ;; opam-installer is used as a tool and not as a library, we can use the
+     ;; OCaml 4.14 compiled opam until opam is compatible with OCaml 5.0.
+     `((ocaml5.0-variant . ,(delay opam-installer))))))
+
+(define ocaml-opam-repository
+  (package
+    (inherit ocaml-opam-core)
+    (name "ocaml-opam-repository")
+    (inputs '())
+    (propagated-inputs (list ocaml-opam-format))
+    (arguments `(#:package "opam-repository"
+                 ;; tests are run with the opam package
+                 #:tests? #f
+                 #:phases %standard-phases))))
+
+(define ocaml-opam-state
+  (package
+    (inherit ocaml-opam-core)
+    (name "ocaml-opam-state")
+    (arguments `(#:package "opam-state"
+                 ;; tests are run with the opam package
+                 #:tests? #f
+                 #:phases
+                 (modify-phases %standard-phases
+                   (add-before 'build 'pre-build
+                     (lambda* (#:key inputs make-flags #:allow-other-keys)
+                       (let ((bwrap (search-input-file inputs "/bin/bwrap")))
+                         ;; Use bwrap from the store directly.
+                         (substitute* "src/state/shellscripts/bwrap.sh"
+                           (("-v bwrap") (string-append "-v " bwrap))
+                           (("exec bwrap") (string-append "exec " bwrap))
+                           ;; Mount /gnu and /run/current-system in the
+                           ;; isolated environment when building with opam.
+                           ;; This is necessary for packages to find external
+                           ;; dependencies, such as a C compiler, make, etc...
+                           (("^add_sys_mounts /usr")
+                            (string-append "add_sys_mounts "
+                                           (%store-directory)
+                                           " /run/current-system /usr")))))))))
+    (inputs (list bubblewrap))
+    (propagated-inputs (list ocaml-opam-repository))))
+
+(define ocaml-opam-solver
+  (package
+    (inherit ocaml-opam-core)
+    (name "ocaml-opam-solver")
+    (inputs '())
+    (propagated-inputs (list ocaml-opam-format
+                             ocaml-mccs
+                             ocaml-dose3))
+    (arguments `(#:package "opam-solver"
+                 ;; tests are run with the opam package
+                 #:tests? #f
+                 #:phases %standard-phases))))
+
+(define ocaml-opam-client
+  (package
+    (inherit ocaml-opam-core)
+    (name "ocaml-opam-client")
+    (arguments `(#:package "opam-client"
+                 ;; tests are run with the opam package
+                 #:tests? #f
+                 #:phases
+                 (modify-phases %standard-phases
+                   (add-before 'build 'pre-build
+                     (lambda* (#:key inputs make-flags #:allow-other-keys)
+                       (let ((bwrap (search-input-file inputs "/bin/bwrap")))
+                         (substitute* "src/client/opamInitDefaults.ml"
+                           (("\"bwrap\"") (string-append "\"" bwrap "\"")))))))))
+    (inputs (list bubblewrap))
+    (propagated-inputs
+     (list ocaml-opam-state
+           ocaml-opam-solver
+           ocaml-opam-repository
+           ocaml-base64
+           ocaml-re
+           ocaml-cmdliner))))
+
+(define-public opam
+  (package
+    (inherit ocaml-opam-core)
+    (name "opam")
+    (build-system dune-build-system)
     (arguments
-     `(#:phases
+     `(#:package "opam"
+       #:phases
        (modify-phases %standard-phases
-         (add-before 'build 'pre-build
-           (lambda* (#:key inputs make-flags #:allow-other-keys)
-             (let ((bash (assoc-ref inputs "bash"))
-                   (bwrap (search-input-file inputs "/bin/bwrap")))
-               (substitute* "src/core/opamSystem.ml"
-                 (("\"/bin/sh\"")
-                  (string-append "\"" bash "/bin/sh\""))
-                 (("getconf")
-                  (which "getconf")))
-               ;; Use bwrap from the store directly.
-               (substitute* "src/state/shellscripts/bwrap.sh"
-                 (("-v bwrap") (string-append "-v " bwrap))
-                 (("exec bwrap") (string-append "exec " bwrap))
-                 ;; Mount /gnu and /run/current-system in the
-                 ;; isolated environment when building with opam.
-                 ;; This is necessary for packages to find external
-                 ;; dependencies, such as a C compiler, make, etc...
-                 (("^add_sys_mounts /usr")
-                  (string-append "add_sys_mounts "
-                                 (%store-directory)
-                                 " /run/current-system /usr")))
-               (substitute* "src/client/opamInitDefaults.ml"
-                 (("\"bwrap\"") (string-append "\"" bwrap "\""))))))
          (add-before 'check 'prepare-checks
            (lambda* (#:key inputs #:allow-other-keys)
              ;; Opam tests need to run an isolated environment from a writable
@@ -966,22 +1085,11 @@ (define-public opam
                                            "0j9abisx3ifzm66ci3p45mngmz4f0fx7yd9jjxrz3f8w5jffc9ii"))
          ("opam-repo-f372039d" ,(opam-repo "f372039db86a970ef3e662adbfe0d4f5cd980701"
                                            "0ld7fcry6ss6fmrpswvr6bikgx299w97h0gwrjjh7kd7rydsjdws")))))
-    (inputs
-     (list ocaml ncurses curl bubblewrap ocaml-cmdliner ocaml-dose3
-           ocaml-mccs ocaml-opam-file-format ocaml-re))
+    (inputs (list ocaml-opam-client))
     (properties
      ;; OPAM is used as a tool and not as a library, we can use the OCaml 4.14
      ;; compiled opam until opam is compatible with OCaml 5.0.
-     `((ocaml5.0-variant . ,(delay opam))))
-    (home-page "https://opam.ocamlpro.com/")
-    (synopsis "Package manager for OCaml")
-    (description
-     "OPAM is a tool to manage OCaml packages.  It supports multiple
-simultaneous compiler installations, flexible package constraints, and a
-Git-friendly development workflow.")
-
-    ;; The 'LICENSE' file waives some requirements compared to LGPLv3.
-    (license license:lgpl3)))
+     `((ocaml5.0-variant . ,(delay opam))))))
 
 (define-public ocaml-opam-monorepo
   (package
@@ -2204,7 +2312,7 @@ (define-public ocaml-topkg
                 "11ycfk0prqvifm9jca2308gw8a6cjb1hqlgfslbji2cqpan09kpq"))))
     (build-system ocaml-build-system)
     (native-inputs
-     (list opam ocamlbuild))
+     (list opam-installer ocamlbuild))
     (propagated-inputs
      `(("result" ,ocaml-result)))
     (arguments
@@ -2234,7 +2342,7 @@ (define-public ocaml-rresult
                 "0h2mjyzhay1p4k7n0mzaa7hlc7875kiy6m1i3r1n03j6hddpzahi"))))
     (build-system ocaml-build-system)
     (native-inputs
-     (list opam ocamlbuild))
+     (list opam-installer ocamlbuild))
     (propagated-inputs
      `(("topkg" ,ocaml-topkg)))
     (arguments
@@ -2349,7 +2457,7 @@ (define-public ocaml-mtime
                 "1ss4w3qxsfp51d88r0j7dzqs05dbb1xdx11hn1jl9cvd03ma0g9z"))))
     (build-system ocaml-build-system)
     (native-inputs
-     (list ocamlbuild opam))
+     (list ocamlbuild opam-installer))
     (propagated-inputs
      `(("topkg" ,ocaml-topkg)))
     (arguments
@@ -2479,13 +2587,13 @@ (define-public ocaml-fmt
                   "0q8j2in2473xh7k4hfgnppv9qy77f2ih89yp6yhpbp92ba021yzi"))))
     (build-system ocaml-build-system)
     (native-inputs
-     `(("ocamlbuild" ,ocamlbuild)
-       ("opam" ,opam)
-       ("topkg" ,ocaml-topkg)))
+     (list ocamlbuild
+           opam-installer
+           ocaml-topkg))
     (propagated-inputs
-     `(("cmdliner" ,ocaml-cmdliner)
-       ("ocaml-stdlib-shims" ,ocaml-stdlib-shims)
-       ("ocaml-uchar" ,ocaml-uchar)))
+     (list ocaml-cmdliner
+           ocaml-stdlib-shims
+           ocaml-uchar))
     (arguments `(#:tests? #f
                  #:build-flags (list "build" "--with-base-unix" "true"
                                      "--with-cmdliner" "true")
@@ -2526,9 +2634,9 @@ (define-public ocaml-astring
                   "1ykhg9gd3iy7zsgyiy2p9b1wkpqg9irw5pvcqs3sphq71iir4ml6"))))
     (build-system ocaml-build-system)
     (native-inputs
-     `(("ocamlbuild" ,ocamlbuild)
-       ("opam" ,opam)
-       ("topkg" ,ocaml-topkg)))
+     (list ocamlbuild
+           opam-installer
+           ocaml-topkg))
     (arguments
      `(#:tests? #f
        #:build-flags (list "build")
@@ -2748,7 +2856,7 @@ (define-public ocaml-react
                   "16cg4byj8lfbbw96dhh8sks5y9n1c3fshz7f2p8m7wgisqax7bf4"))))
     (build-system ocaml-build-system)
     (native-inputs
-     (list ocamlbuild opam ocaml-topkg))
+     (list ocamlbuild opam-installer ocaml-topkg))
     (arguments
      `(#:tests? #f
        #:build-flags (list "build")
@@ -2872,7 +2980,7 @@ (define-public ocaml-hmap
        #:phases
        (modify-phases %standard-phases
          (delete 'configure))))
-    (native-inputs (list ocaml-topkg ocamlbuild opam))
+    (native-inputs (list ocaml-topkg ocamlbuild opam-installer))
     (home-page "https://erratique.ch/software/hmap")
     (synopsis "Heterogeneous value maps for OCaml")
     (description
@@ -3334,7 +3442,7 @@ (define-public ocaml-logs
        (modify-phases %standard-phases
          (delete 'configure))))
     (native-inputs
-     (list ocamlbuild opam))
+     (list ocamlbuild opam-installer))
     (propagated-inputs
      `(("fmt" ,ocaml-fmt)
        ("lwt" ,ocaml-lwt)
@@ -3368,7 +3476,7 @@ (define-public ocaml-fpath
        (modify-phases %standard-phases
          (delete 'configure))))
     (native-inputs
-     (list ocamlbuild opam))
+     (list ocamlbuild opam-installer))
     (propagated-inputs
      `(("topkg" ,ocaml-topkg)
        ("astring" ,ocaml-astring)))
@@ -3398,7 +3506,7 @@ (define-public ocaml-bos
        (modify-phases %standard-phases
          (delete 'configure))))
     (native-inputs
-     (list ocamlbuild opam))
+     (list ocamlbuild opam-installer))
     (propagated-inputs
      `(("topkg" ,ocaml-topkg)
        ("astring" ,ocaml-astring)
@@ -3472,7 +3580,7 @@ (define-public ocaml-xmlm
        (modify-phases %standard-phases
          (delete 'configure))))
     (native-inputs
-     (list ocamlbuild ocaml-topkg opam))
+     (list ocamlbuild ocaml-topkg opam-installer))
     (home-page "https://erratique.ch/software/xmlm")
     (synopsis "Streaming XML codec for OCaml")
     (description "Xmlm is a streaming codec to decode and encode the XML data
@@ -3613,7 +3721,7 @@ (define-public ocaml-uchar
        (modify-phases %standard-phases
          (delete 'configure))))
     (native-inputs
-     (list ocamlbuild opam))
+     (list ocamlbuild opam-installer))
     (home-page "https://github.com/ocaml/uchar")
     (synopsis "Compatibility library for OCaml's Uchar module")
     (description "The uchar package provides a compatibility library for the
@@ -3639,9 +3747,9 @@ (define-public ocaml-uutf
        (modify-phases %standard-phases
          (delete 'configure))))
     (native-inputs
-     `(("ocamlbuild" ,ocamlbuild)
-       ("opam" ,opam)
-       ("topkg" ,ocaml-topkg)))
+     (list ocamlbuild
+           opam-installer
+           ocaml-topkg))
     (propagated-inputs
      `(("uchar" ,ocaml-uchar)
        ("cmdliner" ,ocaml-cmdliner)))
@@ -3686,7 +3794,7 @@ (define-public ocaml-uunf
              #t)))))
     (native-inputs
      `(("ocamlbuild" ,ocamlbuild)
-       ("opam" ,opam)
+       ("opam-installer" ,opam-installer)
        ("topkg" ,ocaml-topkg)
        ;; Test data is otherwise downloaded with curl
        ("NormalizationTest.txt"
@@ -3727,9 +3835,9 @@ (define-public ocaml-jsonm
        (modify-phases %standard-phases
          (delete 'configure))))
     (native-inputs
-     `(("ocamlbuild" ,ocamlbuild)
-       ("opam" ,opam)
-       ("topkg" ,ocaml-topkg)))
+     (list ocamlbuild
+           opam-installer
+           ocaml-topkg))
     (propagated-inputs
      `(("uutf" ,ocaml-uutf)
        ("cmdliner" ,ocaml-cmdliner)))
@@ -4147,7 +4255,7 @@ (define-public ocaml-ptime
        #:phases (modify-phases %standard-phases
                   (delete 'configure))))
     (propagated-inputs (list ocaml-result js-of-ocaml))
-    (native-inputs (list ocaml-findlib ocamlbuild ocaml-topkg opam))
+    (native-inputs (list ocaml-findlib ocamlbuild ocaml-topkg opam-installer))
     (home-page "https://erratique.ch/software/ptime")
     (synopsis "POSIX time for OCaml")
     (description
@@ -5154,7 +5262,7 @@ (define-public ocaml-uuidm
        (modify-phases %standard-phases
          (delete 'configure))))
     (native-inputs
-     (list ocamlbuild opam))
+     (list ocamlbuild opam-installer))
     (propagated-inputs
      `(("cmdliner" ,ocaml-cmdliner)
        ("topkg" ,ocaml-topkg)))
@@ -5771,12 +5879,8 @@ (define-public ocaml-ocb-stubblr
               ;; Guix doesn't have cc, but it has gcc
               (("\"cc\"") "\"gcc\""))
             #t)))))
-   (inputs
-    `(("topkg" ,ocaml-topkg)
-      ("opam" ,opam)))
-   (native-inputs
-    `(("astring" ,ocaml-astring)
-      ("ocamlbuild" ,ocamlbuild)))
+   (inputs (list ocaml-topkg opam-installer))
+   (native-inputs (list ocaml-astring ocamlbuild))
    (synopsis "OCamlbuild plugin for C stubs")
    (description "Ocb-stubblr is about ten lines of code that you need to
 repeat over, over, over and over again if you are using ocamlbuild to build
@@ -5804,7 +5908,7 @@ (define-public ocaml-tsdl
        (modify-phases %standard-phases
          (delete 'configure))))
     (native-inputs
-     (list ocamlbuild ocaml-astring opam pkg-config))
+     (list ocamlbuild ocaml-astring opam-installer pkg-config))
     (inputs
      `(("topkg" ,ocaml-topkg)
        ("sdl2" ,sdl2)
@@ -9524,7 +9628,7 @@ (define-public ocaml-uucd
     (propagated-inputs
      (list ocaml-xmlm))
     (native-inputs
-     (list opam ocaml-findlib ocamlbuild ocaml-topkg))
+     (list opam-installer ocaml-findlib ocamlbuild ocaml-topkg))
     (home-page "https://erratique.ch/software/uucd")
     (synopsis "Unicode character database decoder for OCaml")
     (description "Uucd is an OCaml module to decode the data of the Unicode
@@ -9552,7 +9656,7 @@ (define-public ocaml-uucp
        (modify-phases %standard-phases
          (delete 'configure))))
     (native-inputs
-     (list opam
+     (list opam-installer
            ocaml-findlib
            ocamlbuild
            ocaml-topkg
@@ -9586,7 +9690,7 @@ (define-public ocaml-uuseg
     (propagated-inputs
      (list ocaml-uucp ocaml-uutf ocaml-cmdliner))
     (native-inputs
-     (list opam ocaml-findlib ocamlbuild ocaml-topkg))
+     (list opam-installer ocaml-findlib ocamlbuild ocaml-topkg))
     (home-page "https://erratique.ch/software/uuseg")
     (synopsis "Unicode text segmentation for OCaml")
     (description "Uuseg is an OCaml library for segmenting Unicode text.  It
@@ -10047,8 +10151,7 @@ (define-public ocaml-afl-persistent
              (invoke "./build.sh")))
          ;; XXX: The tests are already run in the build.sh script.
          (delete 'check))))
-    (native-inputs
-     `(("opam" ,opam)))
+    (native-inputs (list opam-installer))
     (home-page "https://github.com/stedolan/ocaml-afl-persistent")
     (synopsis "Use afl-fuzz in persistent mode")
     (description
