diff --git a/modules/admin/templates/federation.twig b/modules/admin/templates/federation.twig
index bcf5c6fba6b40c62c4ea47e9c393e71a0992cf29..367acbe687aafa8433ac1b35855945af6480c408 100644
--- a/modules/admin/templates/federation.twig
+++ b/modules/admin/templates/federation.twig
@@ -4,7 +4,6 @@
 
 {% block preload %}
 <link rel="stylesheet" href="{{ asset('css/admin.css', 'admin') }}">
-<link rel="preload" href="{{ asset('js/bundle.js') }}" as="script">
 {% endblock %}
 
 {% block content %}
@@ -147,7 +146,3 @@
       </fieldset>
     </form>
 {% endblock %}
-{% block postload %}
-    <script src="{{ asset('js/bundle.js') }}"></script>
-{% endblock %}
-
diff --git a/modules/core/www/assets/js/loginuserpass.js b/modules/core/www/assets/js/loginuserpass.js
index 46d50fc4cefeab39cbe198899d5683a19b790349..8667593a73740436b0ffe96e5afce01819d198e7 100644
--- a/modules/core/www/assets/js/loginuserpass.js
+++ b/modules/core/www/assets/js/loginuserpass.js
@@ -1,5 +1,3 @@
-"use strict";
-
 ready(function () {
     var button = document.getElementById("submit_button");
     button.onclick = function () {
@@ -11,3 +9,4 @@ ready(function () {
         return true;
     };
 });
+
diff --git a/src/js/bundle.js b/src/js/bundle.js
deleted file mode 100644
index 055168c37d696b46522e604acafbe8c9bab8ee15..0000000000000000000000000000000000000000
--- a/src/js/bundle.js
+++ /dev/null
@@ -1,45 +0,0 @@
-"use strict";
-
-import ClipboardJS from "clipboard/dist/clipboard";
-import hljs from  "highlight.js/lib/core";
-import xml from "highlight.js/lib/languages/xml";
-import php from "highlight.js/lib/languages/php";
-import json from "highlight.js/lib/languages/json";
-
-// Expander boxes
-var expandable = document.querySelectorAll('.expandable > .expander');
-expandable.forEach(function (currentValue, index, arr) {
-    currentValue.onclick = function (e) {
-        e.preventDefault();
-
-        var parent = e.currentTarget.parentNode;
-        if (parent.className.match(/(?:^|\s)expanded(?!\S)/)) {
-            parent.className = parent.className.replace(/(?:^|\s)expanded(?!\S)/g , '');
-        } else {
-            parent.className += " expanded";
-        }
-
-        e.currentTarget.blur();
-    }
-});
-
-ready(function () {
-    // Syntax highlight
-    hljs.registerLanguage('xml', xml);
-    hljs.registerLanguage('php', php);
-    hljs.registerLanguage('json', json);
-
-    var codeBoxes = document.querySelectorAll('.code-box-content.xml, .code-box-content.php, .code-box-content.json');
-    codeBoxes.forEach(function (currentValue, index, arr) {
-        hljs.highlightElement(currentValue);
-    });
-
-
-    // Clipboard
-    var clipboard = new ClipboardJS('.copy');
-    clipboard.on('success', function (e) {
-        setTimeout(function () {
-            e.clearSelection();
-        }, 150);
-    });
-});
diff --git a/src/js/bundle/clipboard.js b/src/js/bundle/clipboard.js
new file mode 100644
index 0000000000000000000000000000000000000000..f3dfbeb81b1f602190dfb96c5dbe65607129e1f7
--- /dev/null
+++ b/src/js/bundle/clipboard.js
@@ -0,0 +1,11 @@
+import ClipboardJS from "clipboard/dist/clipboard";
+
+ready(function () {
+    // Clipboard
+    var clipboard = new ClipboardJS('.copy');
+    clipboard.on('success', function (e) {
+        setTimeout(function () {
+            e.clearSelection();
+        }, 150);
+    });
+});
diff --git a/src/js/bundle/expander.js b/src/js/bundle/expander.js
new file mode 100644
index 0000000000000000000000000000000000000000..42bb2e57d75a053e0e7a685756c0a47de89b49b2
--- /dev/null
+++ b/src/js/bundle/expander.js
@@ -0,0 +1,15 @@
+ready(function () {
+    // Expander boxes
+    var expandable = document.querySelectorAll('.expandable > .expander');
+    for (var i = 0; i < expandable.length; i++) {
+        expandable[i].currentValue.onclick = function (e) {
+            var parent = e.currentTarget.parentNode;
+            if (parent.className.match(/(?:^|\s)expanded(?!\S)/)) {
+                parent.className = parent.className.replace(/(?:^|\s)expanded(?!\S)/g , '');
+            } else {
+                parent.className += " expanded";
+            }
+            e.currentTarget.blur();
+        };
+    }
+});
diff --git a/src/js/bundle/highlight.js b/src/js/bundle/highlight.js
new file mode 100644
index 0000000000000000000000000000000000000000..ce7b0728a9c8d10d893282ef17ef21987a87b98f
--- /dev/null
+++ b/src/js/bundle/highlight.js
@@ -0,0 +1,16 @@
+import hljs from  "highlight.js/lib/core";
+import xml from "highlight.js/lib/languages/xml";
+import php from "highlight.js/lib/languages/php";
+import json from "highlight.js/lib/languages/json";
+
+ready(function () {
+    // Syntax highlight
+    hljs.registerLanguage('xml', xml);
+    hljs.registerLanguage('php', php);
+    hljs.registerLanguage('json', json);
+
+    var codeBoxes = document.querySelectorAll('.code-box-content.xml, .code-box-content.php, .code-box-content.json');
+    codeBoxes.forEach(function (currentValue, index, arr) {
+        hljs.highlightElement(currentValue);
+    });
+});
diff --git a/src/js/main.js b/src/js/bundle/language.js
similarity index 53%
rename from src/js/main.js
rename to src/js/bundle/language.js
index 47b5079bef402cfcfbb0f541e62227e941d60c22..5734632b4127a9318ad8d19aab5c536767be102d 100644
--- a/src/js/main.js
+++ b/src/js/bundle/language.js
@@ -1,24 +1,3 @@
-"use strict";
-
-import "es5-shim";
-import "es6-shim";
-
-window.readyHandlers = [];
-window.ready = function ready(handler) {
-    window.readyHandlers.push(handler);
-    handleState();
-};
-
-window.handleState = function handleState () {
-    if (document.readyState === 'interactive' || document.readyState === "complete") {
-        while(window.readyHandlers.length > 0) {
-            (window.readyHandlers.shift())();
-        }
-    }
-};
-
-document.onreadystatechange = window.handleState;
-
 ready(function () {
     // Language selector
     var languageSelector = document.getElementById("language-selector");
@@ -54,19 +33,4 @@ ready(function () {
             menuLink.className += " active";
         }
     };
-
-
-    // Expander boxes
-    var expandable = document.querySelectorAll('.expandable > .expander');
-    for (var i = 0; i < expandable.length; i++) {
-        expandable[i].currentValue.onclick = function (e) {
-            var parent = e.currentTarget.parentNode;
-            if (parent.className.match(/(?:^|\s)expanded(?!\S)/)) {
-                parent.className = parent.className.replace(/(?:^|\s)expanded(?!\S)/g , '');
-            } else {
-                parent.className += " expanded";
-            }
-            e.currentTarget.blur();
-        };
-    }
 });
diff --git a/src/js/bundle/main.js b/src/js/bundle/main.js
new file mode 100644
index 0000000000000000000000000000000000000000..dba68635934e40d8972a94801226b4a3b8fa0f49
--- /dev/null
+++ b/src/js/bundle/main.js
@@ -0,0 +1,10 @@
+'use strict';
+
+import "es5-shim";
+import "es6-shim";
+import * as ready from './ready';
+import * as language from './language';
+import * as expander from './expander';
+import * as clipboard from './clipboard';
+import * as highlight from './highlight';
+
diff --git a/src/js/bundle/ready.js b/src/js/bundle/ready.js
new file mode 100644
index 0000000000000000000000000000000000000000..8e6c27a0972b743588bef8dc705dcc284251aed0
--- /dev/null
+++ b/src/js/bundle/ready.js
@@ -0,0 +1,15 @@
+window.readyHandlers = [];
+window.ready = function ready(handler) {
+    window.readyHandlers.push(handler);
+    handleState();
+};
+
+window.handleState = function handleState () {
+    if (document.readyState === 'interactive' || document.readyState === "complete") {
+        while(window.readyHandlers.length > 0) {
+            (window.readyHandlers.shift())();
+        }
+    }
+};
+
+document.onreadystatechange = window.handleState;
diff --git a/src/js/logout/logout.js b/src/js/logout/logout.js
index f4f68966e65e49105a59acf5f8502b9488ed5b22..58598ae7e28d399d5369831a78df169b06417dff 100644
--- a/src/js/logout/logout.js
+++ b/src/js/logout/logout.js
@@ -1,4 +1,4 @@
-"use strict";
+'use strict';
 
 /**
  * This class is used for the logout page.
diff --git a/src/js/logout/main.js b/src/js/logout/main.js
index 929c535bec29dfd887f419dd99c3466e3d1b79a1..3e9eebad9026445ac15cd55662b75086eb92bb59 100644
--- a/src/js/logout/main.js
+++ b/src/js/logout/main.js
@@ -1,4 +1,4 @@
-"use strict";
+'use strict';
 
 import SimpleSAMLLogout from './logout.js';
 
diff --git a/templates/auth_status.twig b/templates/auth_status.twig
index f276f26b92acf42db658bb189be1590bdf2e7b80..731ef1f87cf07a9a0008a19c3bf8cf96766b6b37 100644
--- a/templates/auth_status.twig
+++ b/templates/auth_status.twig
@@ -1,10 +1,6 @@
 {% set pagetitle = 'Authentication status'|trans %}
 {% extends 'base.twig' %}
 
-{% block preload %}
-    <link rel="preload" href="{{ asset('js/main.js') }}" as="script">
-{% endblock %}
-
 {% block content %}
 <h2>{{ pagetitle }}</h2>
 
@@ -120,7 +116,3 @@
     </div>
 {% endif %}
 {% endblock %}
-{% block postload %}
-    <script src="{{ asset('js/bundle.js') }}"></script>
-{% endblock %}
-
diff --git a/templates/base.twig b/templates/base.twig
index 34641fb8b4c985d32f42b87b016c25e42e50a26b..8579598f8a652d598fda769aa805cc699b1ae192 100644
--- a/templates/base.twig
+++ b/templates/base.twig
@@ -12,7 +12,7 @@
     <link rel="stylesheet" href="{{ asset("assets/css/src/default-rtl.css") }}">
     {% endif %}
     <meta name="robots" content="noindex, nofollow">
-    <link rel="preload" href="{{ asset('js/main.js') }}" as="script">
+    <link rel="preload" href="{{ asset('js/bundle.js') }}" as="script">
     {% block preload %}{% endblock %}
   </head>
   <body id="{{ templateId }}">
@@ -30,7 +30,7 @@
     <div id="foot">
       {% block footer %}{% include "_footer.twig" %}{% endblock %}
     </div>
-    <script src="{{ asset('js/main.js') }}"></script>
+    <script src="{{ asset('js/bundle.js') }}"></script>
     {% block postload %}{% endblock %}
   </body>
 </html>
diff --git a/webpack.config.js b/webpack.config.js
index 12a13b08aea240143a40c014d69b8ea26e8d8635..d9c5434cb450eefc459393bb70d661b8a45694cc 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -17,7 +17,7 @@ module.exports = environment => {
     const secondaryBackground = env.hasOwnProperty('secondaryBackground') ? env.secondaryBackground : '#e8410c';
     return {
         entry: {
-            bundle: './src/js/bundle',
+            bundle: './src/js/bundle/main',
             logout: './src/js/logout/main',
             stylesheet: './src/js/style'
         },