diff --git a/.flake8 b/.flake8
deleted file mode 100644
index 788e58561644176c02e75eadf66d728bba92aa9b..0000000000000000000000000000000000000000
--- a/.flake8
+++ /dev/null
@@ -1,4 +0,0 @@
-[flake8]
-max-line-length = 88
-exclude = .git,__pycache__
-ignore = E203,E501,W503
diff --git a/.isort.cfg b/.isort.cfg
deleted file mode 100644
index 093478078cf1870bbaa1646464875dc903afd8e6..0000000000000000000000000000000000000000
--- a/.isort.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-[settings]
-# Compatible with black
-profile = black
-
-default_section=FIRSTPARTY
-known_first_party = arkindex,arkindex_common,arkindex_worker
-known_third_party =PIL,apistar,gitlab,gnupg,peewee,playhouse,pytest,requests,responses,setuptools,sh,shapely,tenacity,yaml,zstandard
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 6582747024585df8b13de884b8b3f4f723dd1bfe..77228da4760d3f2d5944bdd578f234fe40af5b9c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,19 +1,15 @@
 repos:
-  - repo: https://github.com/PyCQA/isort
-    rev: 5.12.0
+  - repo: https://github.com/astral-sh/ruff-pre-commit
+    # Ruff version.
+    rev: v0.0.278
     hooks:
-      - id: isort
+      - id: ruff
+        args: [--fix, --exit-non-zero-on-fix]
+        exclude: "^worker-{{cookiecutter.slug}}/"
   - repo: https://github.com/ambv/black
     rev: 23.1.0
     hooks:
     - id: black
-  - repo: https://github.com/pycqa/flake8
-    rev: 6.0.0
-    hooks:
-      - id: flake8
-        additional_dependencies:
-          - 'flake8-coding==1.3.2'
-          - 'flake8-debugger==4.1.2'
   - repo: https://github.com/pre-commit/pre-commit-hooks
     rev: v4.4.0
     hooks:
diff --git a/docs-requirements.txt b/docs-requirements.txt
index b27162d3fea9fc47eb4e5ccb8db37a790a6a5263..c3b959f6bba7e5fe1614a02e941bd1d08bd44812 100644
--- a/docs-requirements.txt
+++ b/docs-requirements.txt
@@ -1,7 +1,7 @@
-black==23.3.0
+black==23.7.0
 doc8==1.1.1
-mkdocs==1.4.3
-mkdocs-material==9.1.14
-mkdocstrings==0.21.2
-mkdocstrings-python==1.0.0
+mkdocs==1.5.2
+mkdocs-material==9.1.21
+mkdocstrings==0.22.0
+mkdocstrings-python==1.3.0
 recommonmark==0.7.1
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000000000000000000000000000000000000..debb3e7c4e6d4b9e74facaada51df8523e87f42b
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,24 @@
+[tool.ruff]
+exclude = [".git", "__pycache__"]
+ignore = ["E501"]
+select = ["E", "F", "T1", "W", "I"]
+
+[tool.ruff.isort]
+known-first-party = ["arkindex", "arkindex_common", "arkindex_worker"]
+known-third-party = [
+    "PIL",
+    "apistar",
+    "gitlab",
+    "gnupg",
+    "peewee",
+    "playhouse",
+    "pytest",
+    "requests",
+    "responses",
+    "setuptools",
+    "sh",
+    "shapely",
+    "tenacity",
+    "yaml",
+    "zstandard",
+]
diff --git a/requirements.txt b/requirements.txt
index ae1233eb4b53032b0b83f81547c347fb634473d9..6174bf3424f1a3be5b5eb358913c63467d939fb2 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,10 +1,10 @@
-arkindex-client==1.0.12
-peewee==3.16.2
-Pillow==9.5.0
+arkindex-client==1.0.13
+peewee==3.16.3
+Pillow==10.0.0
 pymdown-extensions==10.1
-python-gitlab==3.14.0
+python-gitlab==3.15.0
 python-gnupg==0.5.0
-sh==2.0.4
+sh==2.0.6
 shapely==2.0.1
-tenacity==8.2.2
+tenacity==8.2.3
 zstandard==0.21.0
diff --git a/tests-requirements.txt b/tests-requirements.txt
index d69905b3322fca86694fabb461de9f43ba669efd..0dfed5189ab30a4e6287121681ee076b6ee927f4 100644
--- a/tests-requirements.txt
+++ b/tests-requirements.txt
@@ -1,3 +1,3 @@
-pytest==7.3.1
-pytest-mock==3.10.0
+pytest==7.4.0
+pytest-mock==3.11.1
 pytest-responses==0.5.1
diff --git a/tests/test_elements_worker/test_transcriptions.py b/tests/test_elements_worker/test_transcriptions.py
index 70bebc9084220a29ad7cf13352654b2a7694a8da..c6e03d6215db5dacd7a6353d46287034425ce575 100644
--- a/tests/test_elements_worker/test_transcriptions.py
+++ b/tests/test_elements_worker/test_transcriptions.py
@@ -1978,7 +1978,9 @@ def test_list_transcriptions_with_cache(
     # Query database through cache
     transcriptions = mock_elements_worker_with_cache.list_transcriptions(**filters)
     assert transcriptions.count() == len(expected_ids)
-    for transcription, expected_id in zip(transcriptions.order_by("id"), expected_ids):
+    for transcription, expected_id in zip(
+        transcriptions.order_by(CachedTranscription.id), expected_ids
+    ):
         assert transcription.id == UUID(expected_id)
 
     # Check the worker never hits the API for elements
diff --git a/worker-{{cookiecutter.slug}}/.flake8 b/worker-{{cookiecutter.slug}}/.flake8
deleted file mode 100644
index 7a3797fc6b71677df500d8386cf70e3173a7f79f..0000000000000000000000000000000000000000
--- a/worker-{{cookiecutter.slug}}/.flake8
+++ /dev/null
@@ -1,4 +0,0 @@
-[flake8]
-max-line-length = 150
-exclude = .git,__pycache__
-ignore = E203,E501,W503
diff --git a/worker-{{cookiecutter.slug}}/.isort.cfg b/worker-{{cookiecutter.slug}}/.isort.cfg
deleted file mode 100644
index f5257078ed83767ea2142f9099320f0f4319ee56..0000000000000000000000000000000000000000
--- a/worker-{{cookiecutter.slug}}/.isort.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-[settings]
-# Compatible with black
-profile = black
-
-default_section=FIRSTPARTY
-known_first_party = arkindex,arkindex_worker
-known_third_party = pytest,setuptools
diff --git a/worker-{{cookiecutter.slug}}/.pre-commit-config.yaml b/worker-{{cookiecutter.slug}}/.pre-commit-config.yaml
index 93d07e6993e07300b856e6c8457e9074805baa49..91c7412f7437ef4066ba4193502b99c510bb347b 100644
--- a/worker-{{cookiecutter.slug}}/.pre-commit-config.yaml
+++ b/worker-{{cookiecutter.slug}}/.pre-commit-config.yaml
@@ -1,19 +1,14 @@
 repos:
-  - repo: https://github.com/PyCQA/isort
-    rev: 5.12.0
+  - repo: https://github.com/astral-sh/ruff-pre-commit
+    # Ruff version.
+    rev: v0.0.278
     hooks:
-      - id: isort
+      - id: ruff
+        args: [--fix, --exit-non-zero-on-fix]
   - repo: https://github.com/ambv/black
     rev: 23.1.0
     hooks:
     - id: black
-  - repo: https://github.com/pycqa/flake8
-    rev: 6.0.0
-    hooks:
-      - id: flake8
-        additional_dependencies:
-          - 'flake8-coding==1.3.2'
-          - 'flake8-debugger==4.1.2'
   - repo: https://github.com/pre-commit/pre-commit-hooks
     rev: v4.4.0
     hooks:
diff --git a/worker-{{cookiecutter.slug}}/pyproject.toml b/worker-{{cookiecutter.slug}}/pyproject.toml
new file mode 100644
index 0000000000000000000000000000000000000000..947ec91214fecf969a899d496d14d166af95abb3
--- /dev/null
+++ b/worker-{{cookiecutter.slug}}/pyproject.toml
@@ -0,0 +1,8 @@
+[tool.ruff]
+exclude = [".git", "__pycache__"]
+ignore = ["E501"]
+select = ["E", "F", "T1", "W", "I"]
+
+[tool.ruff.isort]
+known-first-party = ["arkindex", "arkindex_worker"]
+known-third-party = ["pytest", "setuptools"]
diff --git a/worker-{{cookiecutter.slug}}/tests/conftest.py b/worker-{{cookiecutter.slug}}/tests/conftest.py
index 0615ef8fd95d5c0739f0bc744500b93020f503d8..da3b0bc18524432fad2b04e21b38f0460e8d9495 100644
--- a/worker-{{cookiecutter.slug}}/tests/conftest.py
+++ b/worker-{{cookiecutter.slug}}/tests/conftest.py
@@ -7,11 +7,6 @@ from arkindex.mock import MockApiClient
 from arkindex_worker.worker.base import BaseWorker
 
 
-@pytest.fixture
-def mock_api_client() -> MockApiClient:
-    return MockApiClient()
-
-
 @pytest.fixture(autouse=True)
 def setup_environment(responses, monkeypatch) -> None:
     """Setup needed environment variables"""
@@ -31,6 +26,6 @@ def setup_environment(responses, monkeypatch) -> None:
 
     # Setup a mock api client instead of using a real one
     def mock_setup_api_client(self):
-        self.api_client = mock_api_client
+        self.api_client = MockApiClient()
 
     monkeypatch.setattr(BaseWorker, "setup_api_client", mock_setup_api_client)