#! /usr/bin/env python

from setuptools import setup

if __name__ == "__main__":
    setup()

setup.py
setup.py
diff --git a/.github/workflows/codespell-private.yml b/.github/workflows/codespell-private.yml
index 88dd8aa2d1..9aee75d231 100644
--- a/.github/workflows/codespell-private.yml
+++ b/.github/workflows/codespell-private.yml
@@ -34,7 +34,7 @@ jobs:
         run: |
           python --version  # just to check
           pip install -U pip wheel # upgrade to latest pip find 3.5 wheels; wheel to avoid errors
-          pip install --upgrade chardet "setuptools!=47.2.0" docutils setuptools_scm[toml]
+          pip install --upgrade chardet "setuptools!=47.2.0" docutils setuptools_scm[toml] twine
           pip install aspell-python-py3
           pip install -e ".[dev]" # install the codespell dev packages
       - run: codespell --help
diff --git a/Makefile b/Makefile
index 1757974280..d3beed1c45 100644
--- a/Makefile
+++ b/Makefile
@@ -2,11 +2,11 @@ SORT_ARGS := -f -b
 
 DICTIONARIES := codespell_lib/data/dictionary*.txt
 
-PHONY := all check check-dictionaries sort-dictionaries trim-dictionaries check-dictionary sort-dictionary trim-dictionary check-manifest check-distutils flake8 pytest pypi clean
+PHONY := all check check-dictionaries sort-dictionaries trim-dictionaries check-dictionary sort-dictionary trim-dictionary check-manifest check-dist flake8 pytest pypi clean
 
 all: check-dictionaries codespell.1
 
-check: check-dictionaries check-manifest check-distutils flake8 pytest
+check: check-dictionaries check-manifest check-dist flake8 pytest
 
 check-dictionary: check-dictionaries
 sort-dictionary: sort-dictionaries
@@ -47,8 +47,11 @@ trim-dictionaries:
 check-manifest:
 	check-manifest --no-build-isolation
 
-check-distutils:
-	python setup.py check --restructuredtext --strict
+check-dist:
+	$(eval TMP := $(shell mktemp -d))
+	python -m build -o $(TMP)
+	twine check --strict $(TMP)/*
+	rm -rf $(TMP)
 
 flake8:
 	flake8
diff --git a/appveyor.yml b/appveyor.yml
index 79740cac8c..920b3dd814 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -13,9 +13,9 @@ cache:
 
 install:
   - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
+  - "python.exe -m pip install -U pip"
   - "pip install codecov chardet setuptools"
   - "pip install -e \".[dev]\"" # install the codespell dev packages
-  - "python setup.py develop"
 
 build: false  # Not a C# project, build stuff at the test step instead.
 
diff --git a/pyproject.toml b/pyproject.toml
index ed5fbc0dcc..834660b5c3 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -49,7 +49,6 @@ types = [
     "mypy",
     "pytest",
     "types-chardet",
-    "types-setuptools",
 ]
 
 [project.scripts]
diff --git a/setup.py b/setup.py
deleted file mode 100755
index 4fe2f90ac6..0000000000
--- a/setup.py
+++ /dev/null
@@ -1,6 +0,0 @@
-#! /usr/bin/env python
-
-from setuptools import setup
-
-if __name__ == "__main__":
-    setup()

`python setup.py check` → `twine check`
Because `setup.py ...` is deprecated, we need an alternative to `setup.py check` such as `twine`.
