diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000000..b130efbff27
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,28 @@
+# Pre-commit hooks for Pyomo
+# See https://pre-commit.com for more information
+#
+# Setup (one-time):
+# pip install pre-commit
+# pre-commit install
+#
+# After setup, hooks run automatically on 'git commit'
+# To run manually on all files: pre-commit run --all-files
+
+repos:
+ - repo: https://github.com/psf/black
+ rev: 24.10.0
+ hooks:
+ - id: black
+ # Exclusions match pyproject.toml [tool.black] extend-exclude
+ exclude: |
+ (?x)^(
+ examples/pyomobook/python-ch/BadIndent\.py|
+ pyomo/tpl/.*|
+ pyomo/dataportal/_parse_table_datacmds\.py
+ )$
+
+ - repo: https://github.com/crate-ci/typos
+ rev: v1.27.0
+ hooks:
+ - id: typos
+ args: ["--config", ".github/workflows/typos.toml"]
diff --git a/doc/OnlineDocs/contribution_guide.rst b/doc/OnlineDocs/contribution_guide.rst
index ba69afea30a..61f60aa46ed 100644
--- a/doc/OnlineDocs/contribution_guide.rst
+++ b/doc/OnlineDocs/contribution_guide.rst
@@ -49,6 +49,28 @@ determine correct configuration, so if you are running ``black``
indirectly (for example, using an IDE integration), please ensure you
are not overriding the project-level configuration set in that file.
+Pre-commit Hooks (Optional)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To avoid formatting failures in CI, you can set up
+`pre-commit `_ hooks that automatically run
+``black`` and the spell-checker on staged files before each commit:
+
+::
+
+ pip install pre-commit
+ pre-commit install
+
+After installation, hooks run automatically when you run ``git commit``.
+To manually run hooks on all files:
+
+::
+
+ pre-commit run --all-files
+
+This is optional but recommended, as it catches formatting and spelling
+issues locally before they reach CI.
+
Online Pyomo documentation is generated using `Sphinx `_
with the ``napoleon`` extension enabled. For API documentation we use of one of these
`supported styles for docstrings `_,