diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 95b947aedaa43e77ce39bee7f9828153690c8357..2dff7dc445ee3b176280e0cff8f4ce396e73a3bc 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -30,27 +30,11 @@ repos:
       - id: clang-format
         types_or: [c++, c, cuda]
 
-  - repo: https://github.com/psf/black-pre-commit-mirror
-    rev: 24.10.0 # Use the latest stable version
-    hooks:
-      - id: black-jupyter
-
-  - repo: https://github.com/pycqa/isort
-    rev: 5.13.2
-    hooks:
-      - id: isort
-        name: isort (python)
-
-  - repo: https://github.com/Lucas-C/pre-commit-hooks
-    rev: "v1.5.5"
-    hooks:
-      - id: remove-tabs
-
   - repo: https://github.com/charliermarsh/ruff-pre-commit
     rev: v0.7.4 # Use the latest version
     hooks:
       - id: ruff
-        args: ["--fix", "--show-fixes"]
+        args: ["--fix", "--exit-non-zero-on-fix", "--show-fixes"]
 
   - repo: https://github.com/cheshirekow/cmake-format-precommit
     rev: v0.6.13
@@ -58,22 +42,3 @@ repos:
       - id: cmake-format
         types: [file]
         files: (\.cmake|CMakeLists.txt)(.in)?$
-
-  # - repo: https://github.com/codespell-project/codespell
-  #   rev: v
-  #   hooks:
-  #     - id: codespell
-  #       args: ["-L", "sur,falsy,gaus,hist,lsit,nd,parms,retur,ue,ba,claus,fo"]
-
-  # - repo: https://github.com/pre-commit/pygrep-hooks
-  #   rev: v
-  #   hooks:
-  #     - id: rst-backticks
-  #     - id: rst-directive-colons
-  #     - id: rst-inline-touching-normal
-
-  # - repo: https://github.com/shellcheck-py/shellcheck-py
-  #   rev: v0.9.0.5
-  #   hooks:
-  #     - id: shellcheck
-  #       stages: [manual]
diff --git a/notebooks/example.ipynb b/notebooks/example.ipynb
index 4952e58d93d00a312450685b211f4335d4e5448a..d9eedf5e2c34beeac71a43647f5a0ef33c83f78b 100644
--- a/notebooks/example.ipynb
+++ b/notebooks/example.ipynb
@@ -48,8 +48,7 @@
     "import pylint.lint\n",
     "from pylint.reporters import JSONReporter\n",
     "\n",
-    "# Adjust PYTHONPATH\n",
-    "# sys.path.append('/datafs/users/dingxf/neutrino-physics-tutorial/scikit-build-cpp-python')\n",
+    "root = \"/datafs/users/dingxf/neutrino-physics-tutorial/scikit-build-cpp-python\"\n",
     "\n",
     "# Define the Pylint options\n",
     "pylint_options = [\n",
@@ -58,7 +57,7 @@
     "    \"--extension-pkg-allow-list=simulation._csrc._hello\",\n",
     "    \"--prefer-stubs=true\",\n",
     "    \"--clear-cache-post-run=y\",\n",
-    "    \"/datafs/users/dingxf/neutrino-physics-tutorial/scikit-build-cpp-python/python/myproj/simulation/core.py\",  # The file you want to lint\n",
+    "    f\"{root}/python/myproj/simulation/core.py\",  # The file you want to lint\n",
     "]\n",
     "\n",
     "# Create a StringIO buffer to capture Pylint output\n",
diff --git a/pyproject.toml b/pyproject.toml
index 4edd5205b96113c6c4b666ba78a518d69bc1ce2e..7c1f46e1f60190489ebaeda45c99b3123aad6513 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -67,3 +67,13 @@ disable = [
 
 [tool.pylint.MASTER]
 extension-pkg-allow-list = "myproj.simulation"
+
+[tool.ruff.lint]
+select = [
+    "E", # pycodestyle
+    "F", # Pyflakes
+    "UP", # pyupgrade
+    "B", # flake8-bugbear
+    "SIM", # flake8-simplify
+    "I", # isort
+]