diff --git a/.husky/.gitignore b/.husky/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..31354ec1389994b5f6708c7d915fdcc6bb76ba6e
--- /dev/null
+++ b/.husky/.gitignore
@@ -0,0 +1 @@
+_
diff --git a/.husky/commit-msg b/.husky/commit-msg
new file mode 100755
index 0000000000000000000000000000000000000000..0bd658f49625bb80327470bbd59bc134fdc9d1e3
--- /dev/null
+++ b/.husky/commit-msg
@@ -0,0 +1,4 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+npx --no-install commitlint --edit "$1"
diff --git a/.husky/pre-commit b/.husky/pre-commit
new file mode 100755
index 0000000000000000000000000000000000000000..d57c0be1d3b463d66295d0bf4effceb4a5e49fae
--- /dev/null
+++ b/.husky/pre-commit
@@ -0,0 +1,11 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+npm run typecheck
+npx lint-staged
+
+# CaptainHook 5.10.0
+
+INTERACTIVE="--no-interaction"
+
+vendor/bin/captainhook $INTERACTIVE --configuration=captainhook.json --bootstrap=vendor/autoload.php hook:pre-commit "$@" <&0
diff --git a/.husky/pre-push b/.husky/pre-push
new file mode 100755
index 0000000000000000000000000000000000000000..9b4d0f8061671be7c6ff251bae2d5b9ab8334c34
--- /dev/null
+++ b/.husky/pre-push
@@ -0,0 +1,8 @@
+#!/bin/sh
+. "$(dirname "$0")/_/husky.sh"
+
+# CaptainHook 5.10.0
+
+INTERACTIVE="--no-interaction"
+
+vendor/bin/captainhook $INTERACTIVE --configuration=captainhook.json --bootstrap=vendor/autoload.php hook:pre-push "$@" <&0
diff --git a/Dockerfile b/Dockerfile
index 8d87e30d721e32e8a3cb75c466e17951f5e06655..c8fbaedf74f03a0c1ea7e1eeb51fc1af82065f30 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -13,7 +13,7 @@ COPY . /castopod-host
 WORKDIR /castopod-host
 
 # Install composer
-COPY --from=composer /usr/bin/composer /usr/bin/composer
+COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
 
 # Install npm
 RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
@@ -21,6 +21,9 @@ RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
 RUN apt-get update && \
     apt-get install -y nodejs
 
+# update npm to latest version
+RUN npm install --global npm
+
 # Install git + vim
 RUN apt-get update && \
     apt-get upgrade -y && \
diff --git a/composer.json b/composer.json
index 316ee12d145b41517132fd491f097bbe450dd291..5e8c7749c58e04c7ad57c4c87f6b95691fa9b938 100644
--- a/composer.json
+++ b/composer.json
@@ -27,7 +27,6 @@
     "phpunit/phpunit": "^9.5.4",
     "rector/rector": "^0.11.5",
     "captainhook/captainhook": "^5.10.0",
-    "captainhook/plugin-composer": "^5.2",
     "phpstan/phpstan": "^0.12.85",
     "phpstan/extension-installer": "^1.1.0",
     "rector/rector-phpstan-rules": "^0.2.9",
@@ -74,11 +73,6 @@
       "@php vendor/podlibre/podcast-namespace/src/ReversedTaxonomyGenerate.php https://raw.githubusercontent.com/Podcastindex-org/podcast-namespace/main/taxonomy-en.json >  vendor/podlibre/podcast-namespace/src/ReversedTaxonomy.php"
     ]
   },
-  "extra": {
-    "captainhook": {
-      "force-install": true
-    }
-  },
   "support": {
     "source": "https://code.podlibre.org/podlibre/castopod-host.git",
     "discord": "https://castopod.org/discord"
diff --git a/composer.lock b/composer.lock
index 3cb9e81e83d57dce2b8a841f86d837d124f63330..4c1f993a8925b73510898dafa9cf624cbcd19c5e 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "f66c02dfe61b7fe87d93f4db5a1f9c26",
+    "content-hash": "371c6aac9ca489338bf3b3fa06ffdb21",
     "packages": [
         {
             "name": "brick/math",
@@ -2279,61 +2279,6 @@
             ],
             "time": "2021-05-15T12:39:06+00:00"
         },
-        {
-            "name": "captainhook/plugin-composer",
-            "version": "5.3.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/captainhookphp/plugin-composer.git",
-                "reference": "def8812945e0767a45fe0e4db5ed255b7093600a"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/captainhookphp/plugin-composer/zipball/def8812945e0767a45fe0e4db5ed255b7093600a",
-                "reference": "def8812945e0767a45fe0e4db5ed255b7093600a",
-                "shasum": ""
-            },
-            "require": {
-                "captainhook/captainhook": "^5.0",
-                "composer-plugin-api": "^1.1|^2.0",
-                "php": ">=7.1"
-            },
-            "require-dev": {
-                "composer/composer": "*"
-            },
-            "type": "composer-plugin",
-            "extra": {
-                "class": "CaptainHook\\Plugin\\Composer\\ComposerPlugin",
-                "branch-alias": {
-                    "dev-fluffy_hedgehog": "5.0.x-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "CaptainHook\\Plugin\\Composer\\": "src"
-                }
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Andreas Heigl",
-                    "email": "andreas@heigl.org"
-                },
-                {
-                    "name": "Sebastian Feldmann",
-                    "email": "sf@sebastian-feldmann.info"
-                }
-            ],
-            "description": "Composer-Plugin handling your git-hooks",
-            "support": {
-                "issues": "https://github.com/captainhookphp/plugin-composer/issues",
-                "source": "https://github.com/captainhookphp/plugin-composer/tree/5.3.0"
-            },
-            "time": "2021-05-06T15:55:15+00:00"
-        },
         {
             "name": "doctrine/instantiator",
             "version": "1.4.0",
@@ -3790,16 +3735,16 @@
         },
         {
             "name": "rector/rector-phpstan-rules",
-            "version": "0.2.9",
+            "version": "0.2.12",
             "source": {
                 "type": "git",
                 "url": "https://github.com/rectorphp/phpstan-rules.git",
-                "reference": "c53f5fad720fba2c13ab09d885f7be006523458f"
+                "reference": "84b2034aab951be7e86dc6cc7e141ee92a3d115b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/rectorphp/phpstan-rules/zipball/c53f5fad720fba2c13ab09d885f7be006523458f",
-                "reference": "c53f5fad720fba2c13ab09d885f7be006523458f",
+                "url": "https://api.github.com/repos/rectorphp/phpstan-rules/zipball/84b2034aab951be7e86dc6cc7e141ee92a3d115b",
+                "reference": "84b2034aab951be7e86dc6cc7e141ee92a3d115b",
                 "shasum": ""
             },
             "require": {
@@ -3834,9 +3779,9 @@
             "description": "PHPStan rules for Rector projects - with focus on static reflection, constant re-use and Rector design patterns",
             "support": {
                 "issues": "https://github.com/rectorphp/phpstan-rules/issues",
-                "source": "https://github.com/rectorphp/phpstan-rules/tree/0.2.9"
+                "source": "https://github.com/rectorphp/phpstan-rules/tree/0.2.12"
             },
-            "time": "2021-05-15T10:37:29+00:00"
+            "time": "2021-05-20T22:31:19+00:00"
         },
         {
             "name": "sebastian/cli-parser",
diff --git a/package-lock.json b/package-lock.json
index 68d9c489386f595dc906e8b1e63d1cb4ab5da9a1..b70b4d5cc4376ae5e393a025a9589f580ce9900f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -170,12 +170,6 @@
             "node-releases": "^1.1.70"
           }
         },
-        "caniuse-lite": {
-          "version": "1.0.30001204",
-          "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz",
-          "integrity": "sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ==",
-          "dev": true
-        },
         "electron-to-chromium": {
           "version": "1.3.698",
           "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.698.tgz",
@@ -5852,9 +5846,9 @@
       }
     },
     "caniuse-lite": {
-      "version": "1.0.30001165",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001165.tgz",
-      "integrity": "sha512-8cEsSMwXfx7lWSUMA2s08z9dIgsnR5NAqjXP23stdsU3AUWkCr/rr4s4OFtHXn5XXr6+7kam3QFVoYyXNPdJPA==",
+      "version": "1.0.30001228",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz",
+      "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==",
       "dev": true
     },
     "cardinal": {
@@ -6023,6 +6017,12 @@
         }
       }
     },
+    "ci-info": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.1.1.tgz",
+      "integrity": "sha512-kdRWLBIJwdsYJWYJFtAFFYxybguqeF91qpZaggjG5Nf8QKdizFG2hjqvaTXbxFIcYbSaD74KpAXv6BSm17DHEQ==",
+      "dev": true
+    },
     "class-utils": {
       "version": "0.3.6",
       "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
@@ -6664,12 +6664,6 @@
             "node-releases": "^1.1.70"
           }
         },
-        "caniuse-lite": {
-          "version": "1.0.30001204",
-          "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001204.tgz",
-          "integrity": "sha512-JUdjWpcxfJ9IPamy2f5JaRDCaqJOxDzOSKtbdx4rH9VivMd1vIzoPumsJa9LoMIi4Fx2BV2KZOxWhNkBjaYivQ==",
-          "dev": true
-        },
         "electron-to-chromium": {
           "version": "1.3.698",
           "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.698.tgz",
@@ -9701,9 +9695,9 @@
       "dev": true
     },
     "husky": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/husky/-/husky-5.2.0.tgz",
-      "integrity": "sha512-AM8T/auHXRBxlrfPVLKP6jt49GCM2Zz47m8G3FOMsLmTv8Dj/fKVWE0Rh2d4Qrvmy131xEsdQnb3OXRib67PGg==",
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz",
+      "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==",
       "dev": true
     },
     "iconv-lite": {
@@ -9950,6 +9944,15 @@
       "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz",
       "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw=="
     },
+    "is-ci": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz",
+      "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==",
+      "dev": true,
+      "requires": {
+        "ci-info": "^3.1.1"
+      }
+    },
     "is-color-stop": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz",
diff --git a/package.json b/package.json
index 7e065a5a33fd2e877ae379d51461e884250f63cf..f11e6050d537fad48e64f39fc1c06f82f5b3dee8 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,8 @@
     "prettier:fix": "prettier --write --ignore-path .gitignore .",
     "typecheck": "tsc",
     "commit": "git-cz",
-    "release": "semantic-release"
+    "release": "semantic-release",
+    "prepare": "is-ci || husky install"
   },
   "dependencies": {
     "@amcharts/amcharts4": "^4.10.17",
@@ -68,7 +69,8 @@
     "eslint": "^7.22.0",
     "eslint-config-prettier": "^8.1.0",
     "eslint-plugin-prettier": "^3.3.1",
-    "husky": "^5.2.0",
+    "husky": "^6.0.0",
+    "is-ci": "^3.0.0",
     "lint-staged": "^10.5.4",
     "postcss": "^8.2.15",
     "postcss-cli": "^8.3.1",
@@ -88,12 +90,6 @@
     "tailwindcss": "^2.0.4",
     "typescript": "^4.2.3"
   },
-  "husky": {
-    "hooks": {
-      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
-      "pre-commit": "lint-staged"
-    }
-  },
   "lint-staged": {
     "*.{js,ts,css,md,json}": "prettier --write",
     "*.{ts,js}": "eslint --ext js,ts,tsx app/Views/_assets --fix",
diff --git a/scripts/bundle-prepare.sh b/scripts/bundle-prepare.sh
index 71042a3e813190f2e6ae521e6e30cb7f26850fdf..d5aae79b99357db12152bf59a8ad2c974084f945 100644
--- a/scripts/bundle-prepare.sh
+++ b/scripts/bundle-prepare.sh
@@ -1,9 +1,5 @@
 #!/bin/bash
 
-# delete possibly installed git hooks because captainhooks (dev dependency)
-# isn't included in the production dependencies
-rm -rf ./.git/hooks
-
 # install only dev dependencies using the --no-dev option
 php composer.phar install --no-dev --prefer-dist --no-ansi --no-interaction --no-progress --ignore-platform-reqs