diff --git a/type/__package/manifest b/type/__package/manifest
index 9b3a0f275..c0c3428fb 100755
--- a/type/__package/manifest
+++ b/type/__package/manifest
@@ -2,6 +2,7 @@
#
# 2011-2013 Steven Armstrong (steven-cdist at armstrong.cc)
# 2019 Nico Schottelius (nico-cdist at schottelius.org)
+# 2023,2025 Dennis Camera (dennis.camera at riiengineering.ch)
#
# This file is part of skonfig-base.
#
@@ -47,6 +48,7 @@ else
(gentoo) type='emerge' ;;
(suse) type='zypper' ;;
(openwrt) type='opkg' ;;
+ (netbsd) type='pkgsrc' ;;
(openbsd) type='pkg_openbsd' ;;
(adelie|alpine|chimera) type='apk' ;;
(*)
diff --git a/type/__package_pkgsrc/explorer/install_base b/type/__package_pkgsrc/explorer/install_base
new file mode 100755
index 000000000..2a265cb53
--- /dev/null
+++ b/type/__package_pkgsrc/explorer/install_base
@@ -0,0 +1,31 @@
+#!/bin/sh -e
+#
+# 2025 Dennis Camera (dennis.camera at riiengineering.ch)
+#
+# This file is part of skonfig-base.
+#
+# skonfig-base is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# skonfig-base is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with skonfig-base. If not, see .
+#
+# Prints the directory in which the pkg_install executables are
+# installed in. This explorer is needed because this directory is not
+# in the default $PATH for all operating systems.
+#
+
+# common locations:
+# /usr/sbin: NetBSD
+# /opt/tools/sbin: SmartOS
+# /usr/pkg/sbin: Mac OS X
+PATH=/usr/sbin:/usr/pkg/sbin:/usr/pkg/bin:/opt/tools/sbin:/opt/tools/bin:${PATH}
+
+command -v pkg_add | sed 's|/pkg_add$|/|'
diff --git a/type/__package_pkgsrc/explorer/state b/type/__package_pkgsrc/explorer/state
new file mode 100755
index 000000000..2c4754a8d
--- /dev/null
+++ b/type/__package_pkgsrc/explorer/state
@@ -0,0 +1,57 @@
+#!/bin/sh -e
+#
+# 2025 Dennis Camera (dennis.camera at riiengineering.ch)
+#
+# This file is part of skonfig-base.
+#
+# skonfig-base is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# skonfig-base is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with skonfig-base. If not, see .
+#
+# Prints the current state of the package.
+#
+
+# cf. install_base explorer for paths
+PATH=${PATH}:/usr/sbin:/usr/pkg/sbin:/usr/pkg/bin:/opt/tools/sbin:/opt/tools/bin
+
+if test -f "${__object:?}/parameter/name"
+then
+ name=$(cat "${__object:?}/parameter/name")
+else
+ name=${__object_id:?}
+fi
+
+if test -f "${__object:?}/parameter/version"
+then
+ version=$(cat "${__object:?}/parameter/version")
+ case ${version}
+ in
+ ('<'*|'>'*)
+ ;;
+ (?*)
+ version="-${version}" ;;
+ esac
+fi
+pkgid=${name}${version-}
+
+if pkg_best_match=$(pkg_info -E "${pkgid}")
+then
+ if pkg_info -B "${pkg_best_match}" | grep -qxiF 'automatic=yes'
+ then
+ auto='auto'
+ else
+ auto='manual'
+ fi
+ echo "present ${auto}"
+else
+ echo 'absent'
+fi
diff --git a/type/__package_pkgsrc/gencode-remote b/type/__package_pkgsrc/gencode-remote
new file mode 100755
index 000000000..670eeb187
--- /dev/null
+++ b/type/__package_pkgsrc/gencode-remote
@@ -0,0 +1,94 @@
+#!/bin/sh -e
+#
+# 2025 Dennis Camera (dennis.camera at riiengineering.ch)
+#
+# This file is part of skonfig.
+#
+# skonfig is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# skonfig is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with skonfig. If not, see .
+#
+
+# get the pkg_install base directory or hope the executables are in
+# $PATH if empty
+read -r pkg_install_base <"${__object:?}/explorer/install_base" || :
+
+shquot() {
+ sed -e "s/'/'\\\\''/g" -e "1s/^/'/" -e "\$s/\$/'/" <<-EOF
+ $*
+ EOF
+}
+
+read -r state_is auto_is <"${__object:?}/explorer/state" || :
+state_should=$(cat "${__object:?}/parameter/state")
+
+if test -s "${__object:?}/parameter/name"
+then
+ name=$(cat "${__object:?}/parameter/name")
+else
+ name=${__object_id:?}
+fi
+
+
+# check if there is anything to do
+
+case ${state_should}/${auto_is}
+in
+ (present/auto)
+ # just mark as user installed (the package is already
+ # installed because $auto_is=auto)
+ printf '%spkg_admin unset automatic %s\n' \
+ "${pkg_install_base-}" "$(shquot "${name}")"
+ exit 0
+ ;;
+ ("${state_is}"/*)
+ # nothing to do
+ exit 0
+ ;;
+esac
+
+
+# package installation/removal
+
+if test -s "${__object:?}/parameter/version"
+then
+ version=$(cat "${__object:?}/parameter/version")
+ case ${version}
+ in
+ ('<'*|'>'*)
+ ;;
+ (?*)
+ version="-${version}" ;;
+ esac
+fi
+
+pkgid=${name}${version-}
+
+case ${state_should}
+in
+ (present)
+ if test -s "${__object:?}/parameter/pkg-path"
+ then
+ read -r pkg_path <"${__object:?}/parameter/pkg-path"
+ fi
+
+ ${pkg_path:+printf 'PKG_PATH=%s \\\n' "$(shquot "${pkg_path}")"}
+ printf '%spkg_add -U %s\n' \
+ "${pkg_install_base-}" "$(shquot "${pkgid}")"
+ echo 'installed' >>"${__messages_out:?}"
+ ;;
+ (absent)
+ printf '%spkg_delete -A %s\n' \
+ "${pkg_install_base-}" "$(shquot "${pkgid}")"
+ echo 'removed' >>"${__messages_out:?}"
+ ;;
+esac
diff --git a/type/__package_pkgsrc/man.rst b/type/__package_pkgsrc/man.rst
new file mode 100644
index 000000000..9e4da558d
--- /dev/null
+++ b/type/__package_pkgsrc/man.rst
@@ -0,0 +1,84 @@
+cdist-type__package_pkgsrc(7)
+=============================
+
+NAME
+----
+cdist-type__package_pkgsrc - Manage packages using the pkgsrc package manager.
+
+
+DESCRIPTION
+-----------
+This type can be used to manage packages using the pkgsrc package
+manager. It is the default package manager on NetBSD and SmartOS, but
+is installable on other operating systems, like Illomos or Mac OS X,
+as well.
+
+Please note that this type uses the underlying :strong:`pkg_install`
+commands (:strong:`pkg_add`\ (1), :strong:`pkg_info`\ (1),
+:strong:`pkg_delete`\ (1) & co.) over the more "convenient"
+:strong:`pkgin`\ (1), because they are always available while
+:strong:`pkgin`\ (1) has to be installed manually and it is only a
+wrapper for :strong:`pkg_install` anyway.
+
+This means that special :strong:`pkgin`\ (1) configuration
+(e.g. ``repositories.conf``) will not be respected by this type.
+
+
+OPTIONAL PARAMETERS
+-------------------
+name
+ The name of the package to install.
+
+ Defaults to: ``__object_id``
+version
+ If supplied, use to avoid ambiguity.
+
+ This can be a version number only (to mean exactly this version) or
+ any other package wildcard supported by :strong:`pkg_info`\ (1), e.g.
+ ``>=3.0``, ``>=3.0<4``.
+pkg-path
+ Manually specify a ``PKG_PATH`` to add packages from.
+
+ When not specified, the system default from :strong:`pkg_install.conf`\ (5)
+ or a global evironment variable will be used.
+state
+ One of:
+
+ ``present``
+ the package is installed
+ ``absent``
+ | the package is not installed
+ | Automatically installed packages which are no longer required will be
+ removed as well.
+
+
+EXAMPLES
+--------
+
+.. code-block:: sh
+
+ # Install the htop package
+ __package_pkgsrc htop
+
+ # Install GNU bash 2.05 (if you need such an old version for whatever reason)
+ __package_pkgsrc bash --version '>=2.0<3'
+
+
+SEE ALSO
+--------
+* :strong:`cdist-type__package`\ (7)
+* :strong:`pkg_add`\ (1)
+* https://pkgsrc.org/
+
+
+AUTHORS
+-------
+* Dennis Camera
+
+
+COPYING
+-------
+Copyright \(C) 2025 Dennis Camera.
+You can redistribute it and/or modify it under the terms of the GNU General
+Public License as published by the Free Software Foundation, either version 3 of
+the License, or (at your option) any later version.
diff --git a/type/__package_pkgsrc/parameter/default/state b/type/__package_pkgsrc/parameter/default/state
new file mode 100644
index 000000000..e7f6134fe
--- /dev/null
+++ b/type/__package_pkgsrc/parameter/default/state
@@ -0,0 +1 @@
+present
diff --git a/type/__package_pkgsrc/parameter/optional b/type/__package_pkgsrc/parameter/optional
new file mode 100644
index 000000000..b71fad5f1
--- /dev/null
+++ b/type/__package_pkgsrc/parameter/optional
@@ -0,0 +1,4 @@
+name
+pkg-path
+state
+version