diff --git a/config/paths.js b/config/paths.js
deleted file mode 100644
index 2060badce016cbe023d2af06e9a9015114a77858..0000000000000000000000000000000000000000
--- a/config/paths.js
+++ /dev/null
@@ -1,98 +0,0 @@
-const path = require('path');
-const fs = require('fs');
-const url = require('url');
-
-// Make sure any symlinks in the project folder are resolved:
-// https://github.com/facebook/create-react-app/issues/637
-const appDirectory = fs.realpathSync(process.cwd());
-
-/**
- *
- * @param relativePath
- * @returns {string}
- */
-const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
-
-const envPublicUrl = process.env.PUBLIC_URL;
-
-/**
- *
- * @param inputPath
- * @param needsSlash
- * @returns {*}
- */
-function ensureSlash(inputPath, needsSlash) {
-  const hasSlash = inputPath.endsWith('/');
-  if (hasSlash && !needsSlash) {
-    return inputPath.substr(0, inputPath.length - 1);
-  } else if (!hasSlash && needsSlash) {
-    return `${inputPath}/`;
-  } else {
-    return inputPath;
-  }
-}
-
-/**
- *
- * @param appPackageJson
- * @returns {string | *}
- */
-const getPublicUrl = appPackageJson => envPublicUrl || require(appPackageJson).homepage;
-
-/**
- *
- * @param appPackageJson
- * @returns {*}
- */
-function getServedPath(appPackageJson) {
-  const publicUrl = getPublicUrl(appPackageJson);
-  const servedUrl =
-    envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/');
-  return ensureSlash(servedUrl, true);
-}
-
-const moduleFileExtensions = [
-  'web.mjs',
-  'mjs',
-  'web.js',
-  'js',
-  'web.ts',
-  'ts',
-  'web.tsx',
-  'tsx',
-  'json',
-  'web.jsx',
-  'jsx',
-];
-
-/**
- *
- * @param resolveFn
- * @param filePath
- * @returns {*}
- */
-const resolveModule = (resolveFn, filePath) => {
-  const extension = moduleFileExtensions.find(extension => fs.existsSync(resolveFn(`${filePath}.${extension}`)));
-
-  if (extension) {
-    return resolveFn(`${filePath}.${extension}`);
-  }
-
-  return resolveFn(`${filePath}.js`);
-};
-
-module.exports = {
-  dotenv: resolveApp('.env'),
-  appPath: resolveApp('.'),
-  appBuild: resolveApp('build'),
-  appDist: resolveApp('dist'),
-  appIndexJs: resolveModule(resolveApp, 'src/index'),
-  appPackageJson: resolveApp('package.json'),
-  appSrc: resolveApp('src'),
-  testsSetup: resolveModule(resolveApp, 'src/setupTests'),
-  appNodeModules: resolveApp('node_modules'),
-  publicUrl: getPublicUrl(resolveApp('package.json')),
-  servedPath: getServedPath(resolveApp('package.json')),
-};
-
-module.exports.moduleFileExtensions = moduleFileExtensions;
diff --git a/package.json b/package.json
index 79c79108a42e6a4bd39b6e9064a4138b4ace11eb..0dd587d6cebf14d8f13c83e58caf9f0424e18185 100644
--- a/package.json
+++ b/package.json
@@ -86,7 +86,9 @@
     "@babel/preset-env": "^7.10.3",
     "@babel/preset-react": "^7.10.1",
     "@pmmmwh/react-refresh-webpack-plugin": "^0.3.3",
-    "babel-eslint": "10.1.0",
+    "@typescript-eslint/eslint-plugin": "^4.21.0",
+    "@typescript-eslint/parser": "^4.21.0",
+    "babel-eslint": "^10.1.0",
     "babel-jest": "^26.0.1",
     "babel-loader": "^8.0.6",
     "babel-plugin-lodash": "^3.3.4",
@@ -98,15 +100,16 @@
     "core-js": "^3.4.8",
     "enzyme": "^3.10.0",
     "enzyme-adapter-react-16": "^1.15.0",
-    "eslint": "^6.0.0",
+    "eslint": "^7.23.0",
     "eslint-config-airbnb": "^18.2.0",
-    "eslint-config-react-app": "^3.0.5",
+    "eslint-config-react-app": "^6.0.0",
     "eslint-loader": "^4.0.2",
-    "eslint-plugin-flowtype": "^4.7.0",
-    "eslint-plugin-import": "^2.18.0",
-    "eslint-plugin-jest": "^23.16.0",
-    "eslint-plugin-jsx-a11y": "^6.2.3",
-    "eslint-plugin-react": "^7.14.2",
+    "eslint-plugin-flowtype": "^5.6.0",
+    "eslint-plugin-import": "^2.22.1",
+    "eslint-plugin-jest": "^24.0.0",
+    "eslint-plugin-jsx-a11y": "^6.4.1",
+    "eslint-plugin-react": "^7.23.2",
+    "eslint-plugin-react-hooks": "^4.2.0",
     "glob": "^7.1.4",
     "http-server": "^0.12.3",
     "jest": "^26.0.1",
@@ -115,7 +118,6 @@
     "jsdom": "15.1.1",
     "puppeteer": "^4.0.0",
     "react": "^16.8.6",
-    "react-dev-utils": "^10.2.1",
     "react-dom": "^16.8.6",
     "react-refresh": "^0.8.3",
     "redux-mock-store": "^1.5.1",
diff --git a/src/extend/PluginProvider.js b/src/extend/PluginProvider.js
index ee9269e58f462c7a7500be9c946bd698d2604e0b..784191184315d514b59b25a64e23bd1897bc9f1b 100644
--- a/src/extend/PluginProvider.js
+++ b/src/extend/PluginProvider.js
@@ -16,7 +16,7 @@ export default function PluginProvider(props) {
     const connectedPlugins = connectPluginsToStore(plugins);
     addPluginsToCompanionWindowsRegistry(connectedPlugins);
     setPluginMap(createTargetToPluginMapping(connectedPlugins));
-  }, []);
+  }, [plugins]);
 
   return (
     <PluginContext.Provider value={pluginMap}>
diff --git a/src/i18n.js b/src/i18n.js
index 5742a271d834641d659091427d21f1a002e2fbb5..168dcb81f9af01140164293376c5fb7dfdd4c9a0 100644
--- a/src/i18n.js
+++ b/src/i18n.js
@@ -14,8 +14,10 @@ import sr from './locales/sr/translation.json';
 import lt from './locales/lt/translation.json';
 import vi from './locales/vi/translation.json';
 
-export default () => {
-  // Load translations for each language
+/**
+ * Load translations for each language
+ */
+function createI18nInstance() {
   const resources = {
     ar,
     de,
@@ -43,4 +45,6 @@ export default () => {
   });
 
   return instance;
-};
+}
+
+export default createI18nInstance;
diff --git a/src/lib/htmlRules.js b/src/lib/htmlRules.js
index 43fd823275b1bf50c98b29f68b4f8ef34353c09a..f50c3ae246f8b1219a2fe40af0a7947e8c798be9 100644
--- a/src/lib/htmlRules.js
+++ b/src/lib/htmlRules.js
@@ -18,9 +18,11 @@ const mirador2 = {
   ALLOWED_TAGS: ['a', 'b', 'br', 'i', 'img', 'p', 'span', 'strong', 'em', 'ul', 'ol', 'li'],
 };
 
-export default {
+const htmlRules = {
   iiif,
   liberal,
   mirador2,
   noHtml,
 };
+
+export default htmlRules;
diff --git a/src/state/createStore.js b/src/state/createStore.js
index 4797c59ebfe99ea942b02576f4e16bee8db49222..717b0b8915cc9dd00df4b0652a56a4d291b80c65 100644
--- a/src/state/createStore.js
+++ b/src/state/createStore.js
@@ -14,7 +14,7 @@ import settings from '../config/settings';
 /**
  * Configure Store
  */
-export default function (pluginReducers, pluginSagas = []) {
+function configureStore(pluginReducers, pluginSagas = []) {
   const miradorReducer = createRootReducer(pluginReducers);
 
   const rootReducer = settings.state.slice
@@ -38,3 +38,5 @@ export default function (pluginReducers, pluginSagas = []) {
 
   return store;
 }
+
+export default configureStore;
diff --git a/webpack.config.js b/webpack.config.js
index 292c2e3b62e4cf3933bd0a59d2bee331e9c3b649..3f78b6cad3e2a3339c9801046e1b21ef5bb89b0a 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,8 +1,8 @@
 const path = require('path');
+const fs = require('fs');
 const webpack = require('webpack');
 const TerserPlugin = require('terser-webpack-plugin');
 const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
-const paths = require('./config/paths');
 
 /** */
 const baseConfig = mode => ({
@@ -10,7 +10,7 @@ const baseConfig = mode => ({
   module: {
     rules: [
       {
-        include: paths.appPath, // CRL
+        include: path.resolve(fs.realpathSync(process.cwd()), '.'), // CRL
         loader: require.resolve('babel-loader'),
         options: {
           // Save disk space when time isn't as important