diff --git a/cmake/configs/default.cmake b/cmake/configs/default.cmake
index 4f516cb36b..d4e6e5ff86 100644
--- a/cmake/configs/default.cmake
+++ b/cmake/configs/default.cmake
@@ -237,6 +237,7 @@ hunter_default_version(cpp-statsd-client VERSION 1.0.1-42f02b4-p0)
hunter_default_version(cpp_redis VERSION 3.5.0-h1)
hunter_default_version(cppast VERSION 0.0.0-b155d6a-p0)
hunter_default_version(cppcodec VERSION 0.2-p0)
+hunter_default_version(cppduals VERSION 0.9.2)
hunter_default_version(cppfs VERSION 1.3.0)
hunter_default_version(cpr VERSION 1.3.0)
hunter_default_version(cpuinfo VERSION 0.0.0-d5e37ad-p0)
diff --git a/cmake/projects/cppduals/hunter.cmake b/cmake/projects/cppduals/hunter.cmake
new file mode 100644
index 0000000000..fa22f330cb
--- /dev/null
+++ b/cmake/projects/cppduals/hunter.cmake
@@ -0,0 +1,32 @@
+# Copyright (c) 2026, Michael Tesch
+# All rights reserved.
+
+# !!! DO NOT PLACE HEADER GUARDS HERE !!!
+
+include(hunter_add_version)
+include(hunter_cacheable)
+include(hunter_cmake_args)
+include(hunter_download)
+include(hunter_pick_scheme)
+
+hunter_add_version(
+ PACKAGE_NAME
+ cppduals
+ VERSION
+ 0.9.2
+ URL
+ "https://gitlab.com/tesch1/cppduals/-/archive/v0.9.2/cppduals-v0.9.2.tar.gz"
+ SHA1
+ 1478c1fe45269470182f0222056c27ab0e22dda8
+)
+
+hunter_cmake_args(
+ cppduals
+ CMAKE_ARGS
+ CPPDUALS_TESTING=OFF
+ CPPDUALS_BENCHMARK=OFF
+)
+
+hunter_pick_scheme(DEFAULT url_sha1_cmake)
+hunter_cacheable(cppduals)
+hunter_download(PACKAGE_NAME cppduals)
diff --git a/docs/packages/math.rst b/docs/packages/math.rst
index 9fb93fbff2..c4321bd6a1 100644
--- a/docs/packages/math.rst
+++ b/docs/packages/math.rst
@@ -10,6 +10,7 @@ Math
- :ref:`pkg.GSL` - GNU Scientific Library
- :ref:`pkg.HastyNoise` - SIMD open source noise generation library with a large collection of different noise algorithms.
- :ref:`pkg.OpenBLAS` - OpenBLAS is an optimized BLAS library based on GotoBLAS2 1.13 BSD version
+ - :ref:`pkg.cppduals` - header-only dual number library for exact forward-mode automatic differentiation.
- :ref:`pkg.double-conversion` - provides binary-decimal and decimal-binary routines for IEEE doubles.
- :ref:`pkg.gemmlowp` - Low-precision matrix multiplication.
- :ref:`pkg.glm` - header only C++ mathematics library for graphics software based on the OpenGL Shading Language (GLSL) specifications.
diff --git a/docs/packages/pkg/cppduals.rst b/docs/packages/pkg/cppduals.rst
new file mode 100644
index 0000000000..2a03288c98
--- /dev/null
+++ b/docs/packages/pkg/cppduals.rst
@@ -0,0 +1,27 @@
+.. spelling:word-list::
+
+ cppduals
+ autodiff
+
+.. index:: math ; cppduals
+
+.. _pkg.cppduals:
+
+cppduals
+========
+
+- https://gitlab.com/tesch1/cppduals
+- `Documentation `__
+- Maintainer: https://github.com/tesch1
+
+Header-only dual number library for exact forward-mode automatic
+differentiation, with optional Eigen integration.
+
+If you use this in research, please cite
+`doi:10.21105/joss.01487 `__
+(Tesch, JOSS 4(43):1487, 2019).
+
+.. literalinclude:: /../examples/cppduals/CMakeLists.txt
+ :language: cmake
+ :start-after: # DOCUMENTATION_START {
+ :end-before: # DOCUMENTATION_END }
diff --git a/examples/cppduals/CMakeLists.txt b/examples/cppduals/CMakeLists.txt
new file mode 100644
index 0000000000..e22b414afc
--- /dev/null
+++ b/examples/cppduals/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (c) 2026, Michael Tesch
+# All rights reserved.
+
+cmake_minimum_required(VERSION 3.10)
+
+# Emulate HunterGate:
+# * https://github.com/hunter-packages/gate
+include("../common.cmake")
+
+project(download-cppduals)
+
+# DOCUMENTATION_START {
+hunter_add_package(cppduals)
+find_package(cppduals CONFIG REQUIRED)
+
+add_executable(foo foo.cpp)
+target_link_libraries(foo cppduals::duals)
+# DOCUMENTATION_END }
+
+set_target_properties(foo PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED YES)
diff --git a/examples/cppduals/foo.cpp b/examples/cppduals/foo.cpp
new file mode 100644
index 0000000000..d0710ed17e
--- /dev/null
+++ b/examples/cppduals/foo.cpp
@@ -0,0 +1,8 @@
+#include // duals::dual
+#include // std::cout
+
+int main() {
+ using namespace duals::literals;
+ auto y = (2.0 + 1.0_e) * sin(2.0 + 1.0_e);
+ std::cout << "f(2) = " << rpart(y) << ", f'(2) = " << dpart(y) << std::endl;
+}