diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000000000000000000000000000000000000..7e36c1ae31c5b2a746ca7b39aad0dc1421c1739b
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,64 @@
+[build-system]
+requires = ['setuptools']
+build-backend = 'setuptools.build_meta'
+
+[project]
+name = 'kgb'
+description = 'Utilities for spying on function calls in unit tests.'
+authors = [
+    {name = 'Beanbag, Inc.', email = 'questions@beanbaginc.com'},
+]
+license = { text = 'MIT' }
+readme = 'README.rst'
+requires-python = '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*'
+dynamic =  ['version']
+
+keywords = [
+    'pytest',
+    'unit tests',
+    'spies',
+]
+
+classifiers = [
+    'Development Status :: 5 - Production/Stable',
+    'Environment :: Other Environment',
+    'Framework :: Pytest',
+    'Intended Audience :: Developers',
+    'License :: OSI Approved :: MIT License',
+    'Operating System :: OS Independent',
+    'Programming Language :: Python',
+    'Programming Language :: Python :: 2',
+    'Programming Language :: Python :: 2.7',
+    'Programming Language :: Python :: 3',
+    'Programming Language :: Python :: 3.6',
+    'Programming Language :: Python :: 3.7',
+    'Programming Language :: Python :: 3.8',
+    'Programming Language :: Python :: 3.9',
+    'Programming Language :: Python :: 3.10',
+    'Programming Language :: Python :: 3.11',
+    'Programming Language :: Python :: 3.12',
+    'Programming Language :: Python :: 3.13',
+    'Topic :: Software Development',
+    'Topic :: Software Development :: Libraries :: Python Modules',
+    'Topic :: Software Development :: Testing',
+]
+
+
+[project.urls]
+Homepage = 'https://github.com/beanbaginc/kgb'
+Documentation = 'https://github.com/beanbaginc/kgb'
+Repository = 'https://github.com/beanbaginc/kgb'
+
+
+[project.entry-points."pytest11"]
+kgb = 'kgb.pytest_plugin'
+
+
+[tool.setuptools.dynamic]
+version = { attr = 'kgb.get_package_version' }
+
+
+[tool.setuptools.packages.find]
+where = ['.']
+include = ['kgb*']
+namespaces = false
diff --git a/setup.py b/setup.py
deleted file mode 100755
index 4f6e01cb53faef7df94cc228d5fd25ade4525cfc..0000000000000000000000000000000000000000
--- a/setup.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env python
-#
-# setup.py -- Installation for kgb
-#
-# Copyright (C) 2013 Beanbag, Inc.
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# 'Software'), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be included
-# in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-from setuptools import find_packages, setup
-
-from kgb import get_package_version
-
-
-PACKAGE_NAME = 'kgb'
-
-
-with open('README.rst', 'r') as fp:
-    readme = fp.read()
-
-
-setup(name=PACKAGE_NAME,
-      version=get_package_version(),
-      license='MIT',
-      description='Utilities for spying on function calls in unit tests.',
-      long_description=readme,
-      url='https://github.com/beanbaginc/kgb',
-      packages=find_packages(),
-      maintainer='Christian Hammond',
-      maintainer_email='christian@beanbaginc.com',
-      entry_points={
-          'pytest11': [
-              'kgb = kgb.pytest_plugin',
-          ],
-      },
-      python_requires=','.join([
-          '>=2.7',
-          '!=3.0.*',
-          '!=3.1.*',
-          '!=3.2.*',
-          '!=3.3.*',
-          '!=3.4.*',
-          '!=3.5.*',
-      ]),
-      classifiers=[
-          'Development Status :: 5 - Production/Stable',
-          'Environment :: Other Environment',
-          'Framework :: Pytest',
-          'Intended Audience :: Developers',
-          'License :: OSI Approved :: MIT License',
-          'Operating System :: OS Independent',
-          'Programming Language :: Python',
-          'Programming Language :: Python :: 2',
-          'Programming Language :: Python :: 2.7',
-          'Programming Language :: Python :: 3',
-          'Programming Language :: Python :: 3.6',
-          'Programming Language :: Python :: 3.7',
-          'Programming Language :: Python :: 3.8',
-          'Programming Language :: Python :: 3.9',
-          'Programming Language :: Python :: 3.10',
-          'Programming Language :: Python :: 3.11',
-          'Topic :: Software Development',
-          'Topic :: Software Development :: Libraries :: Python Modules',
-          'Topic :: Software Development :: Testing',
-      ]
-)
