diff --git a/testing/ocaml-uunf/APKBUILD b/testing/ocaml-uunf/APKBUILD
new file mode 100644
index 0000000000000000000000000000000000000000..04eeb1ad9200bcefb953accb3aadd9129391a607
--- /dev/null
+++ b/testing/ocaml-uunf/APKBUILD
@@ -0,0 +1,71 @@
+# Contributor: rubicon <rubicon@mailo.com>
+# Maintainer:
+pkgname=ocaml-uunf
+_pkgname=uunf
+pkgver=14.0.0
+pkgrel=0
+pkgdesc="Unicode text normalization for OCaml"
+url="https://erratique.ch/software/uunf"
+# riscv64: restricted by ocaml aport
+# ppc64le: ocamlopt exited with code 2 while compiling uunf_data.ml
+arch="all !riscv64 !ppc64le"
+license="ISC"
+depends="ocaml-runtime"
+depends_dev="$pkgname=$pkgver-r$pkgrel"
+makedepends="
+	ocaml
+	ocaml-compiler-libs
+	ocaml-findlib
+	ocamlbuild
+	ocaml-topkg
+	ocaml-cmdliner-dev
+	ocaml-uucd-dev
+	ocaml-uutf-dev
+	cmd:opam-installer
+	"
+options="!check"  # no tests provided
+subpackages="$pkgname-dev"
+source="$pkgname-$pkgver.tar.bz2::https://erratique.ch/software/uunf/releases/uunf-$pkgver.tbz"
+builddir="$srcdir/$_pkgname-$pkgver"
+_ocamldir=usr/lib/ocaml
+
+# 32-bit archs
+case "$CARCH" in
+	arm*|x86) options="$options textrels" ;;
+esac
+
+build() {
+	ocaml pkg/pkg.ml build \
+		--with-uutf true \
+		--with-cmdliner true
+}
+
+package() {
+	opam-installer -i \
+		--prefix="$pkgdir/usr" \
+		--libdir="$pkgdir/$_ocamldir" \
+		--docdir="$builddir/.omit" \
+		$_pkgname.install
+}
+
+dev() {
+	default_dev
+
+	cd "$pkgdir"
+
+	local path; for path in $(find $_ocamldir \( \
+			-name '*.cmt' -o \
+			-name '*.cmti' -o \
+			-name '*.cmx' -o \
+			-name '*.cmxa' -o \
+			-name '*.ml' -o \
+			-name '*.mli' \
+		\))
+	do
+		amove "$path"
+	done
+}
+
+sha512sums="
+9aac01483abb8a8a5d68832d7f7692909d61559f2c9b0284c1da293f8115d1100df26e9e4cf7280bda6499ba866f5da2c72c4c21ca99a1d594b29d000e9bb051  ocaml-uunf-14.0.0.tar.bz2
+"