diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..c57edf3
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,30 @@
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v4.5.0
+    hooks:
+      - id: trailing-whitespace
+      # Replaces or checks mixed line ending
+      - id: mixed-line-ending
+        args: ['--fix', 'lf']
+        exclude: '.*\.(svg)$'
+      # Forbid files which have a UTF-8 byte-order marker
+      - id: check-byte-order-marker
+      # Checks that non-binary executables have a proper shebang
+      - id: check-executables-have-shebangs
+      # Check for files that contain merge conflict strings.
+      - id: check-merge-conflict
+      # Check for debugger imports and py37+ breakpoint()
+      # calls in python source
+      - id: debug-statements
+      - id: check-yaml
+        files: .*\.(yaml|yml)$
+  - repo: https://opendev.org/openstack/hacking
+    rev: 7.0.0
+    hooks:
+      - id: hacking
+        additional_dependencies: []
+  - repo: https://github.com/asottile/pyupgrade
+    rev: v3.18.0
+    hooks:
+      - id: pyupgrade
+        args: [--py3-only]
diff --git a/test-requirements.txt b/test-requirements.txt
index fdc78c8..59d45db 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,5 +1,3 @@
-hacking>=6.1.0,<6.2.0 # Apache-2.0
-
 coverage>=3.6
 fixtures>=1.3.1
 testtools>=1.4.0
diff --git a/tox.ini b/tox.ini
index d202f25..bf61d79 100644
--- a/tox.ini
+++ b/tox.ini
@@ -22,7 +22,10 @@ commands =
   stestr slowest
 
 [testenv:pep8]
-commands = flake8
+deps =
+  pre-commit>=2.6.0 # MIT
+commands =
+  pre-commit run -a
 
 [testenv:venv]
 commands = {posargs}
diff --git a/yaql/language/parser.out b/yaql/language/parser.out
index 290a5d2..b6b818d 100644
--- a/yaql/language/parser.out
+++ b/yaql/language/parser.out
@@ -89,7 +89,7 @@ OP_U                 : 19
 QUOTED_STRING        : 23
 TRUE                 : 25
 ]                    : 36 37
-error                : 
+error                :
 }                    : 38
 
 Nonterminals, with rules where they appear