diff --git a/karma.conf.js b/karma.conf.js
index 6906e9b910..5309c05067 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -33,8 +33,8 @@ const olm_entry = webpack_config.entry['olm'];
 delete webpack_config['entry'];
 
 // add ./test as a search path for js
-webpack_config.module.loaders.unshift({
-    test: /\.js$/, loader: "babel",
+webpack_config.module.rules.unshift({
+    test: /\.js$/, use: "babel-loader",
     include: [path.resolve('./src'), path.resolve('./test')],
 });
 
@@ -46,8 +46,9 @@ webpack_config.module.noParse.push(/sinon\/pkg\/sinon\.js$/);
 // ?
 webpack_config.resolve.alias['sinon'] = 'sinon/pkg/sinon.js';
 
-webpack_config.resolve.root = [
+webpack_config.resolve.modules = [
     path.resolve('./test'),
+    "node_modules"
 ];
 
 webpack_config.devtool = 'inline-source-map';
diff --git a/package.json b/package.json
index 0e8d62737c..fb71febdd3 100644
--- a/package.json
+++ b/package.json
@@ -33,8 +33,8 @@
     "build:res": "node scripts/copy-res.js",
     "build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
     "build:compile": "npm run reskindex && babel --source-maps -d lib src",
-    "build:bundle": "cross-env NODE_ENV=production webpack -p --progress --bail",
-    "build:bundle:dev": "webpack --optimize-occurence-order --progress --bail",
+    "build:bundle": "cross-env NODE_ENV=production webpack-cli -p --progress --bail --mode production",
+    "build:bundle:dev": "webpack-cli --progress --bail --mode development",
     "build:electron": "npm run clean && npm run build && npm run install:electron && build -wml --ia32 --x64",
     "build": "npm run reskindex && npm run build:res && npm run build:bundle",
     "build:dev": "npm run reskindex && npm run build:res && npm run build:bundle:dev",
@@ -42,7 +42,7 @@
     "install:electron": "install-app-deps",
     "electron": "npm run install:electron && electron .",
     "start:res": "node scripts/copy-res.js -w",
-    "start:js": "webpack-dev-server --output-filename=bundles/_dev_/[name].js --output-chunk-file=bundles/_dev_/[name].js -w --progress",
+    "start:js": "webpack-dev-server --output-filename=bundles/_dev_/[name].js --output-chunk-filename=bundles/_dev_/[name].js -w --progress",
     "start:js:prod": "cross-env NODE_ENV=production webpack-dev-server -w --progress",
     "start": "parallelshell \"npm run reskindex:watch\" \"npm run start:res\" \"npm run start:js\"",
     "start:prod": "parallelshell \"npm run reskindex:watch\" \"npm run start:res\" \"npm run start:js:prod\"",
@@ -58,10 +58,10 @@
     "babel-runtime": "^6.11.6",
     "bluebird": "^3.5.0",
     "browser-request": "^0.3.3",
-    "extract-text-webpack-plugin": "^0.9.1",
+    "extract-text-webpack-plugin": "^4.0.0-beta.0",
     "favico.js": "^0.3.10",
     "matrix-js-sdk": "0.10.1",
-    "matrix-react-sdk": "0.12.2",
+    "matrix-react-sdk": "matrix-org/matrix-react-sdk#develop",
     "modernizr": "^3.1.0",
     "prop-types": "^15.5.10",
     "react": "^15.6.0",
@@ -75,7 +75,7 @@
     "babel-cli": "^6.5.2",
     "babel-core": "^6.14.0",
     "babel-eslint": "^6.1.0",
-    "babel-loader": "^6.2.5",
+    "babel-loader": "^7.1.4",
     "babel-plugin-add-module-exports": "^0.2.1",
     "babel-plugin-transform-async-to-bluebird": "^1.1.1",
     "babel-plugin-transform-class-properties": "^6.16.0",
@@ -101,7 +101,7 @@
     "eslint-plugin-react": "^7.4.0",
     "expect": "^1.16.0",
     "fs-extra": "^0.30.0",
-    "html-webpack-plugin": "^2.24.0",
+    "html-webpack-plugin": "^3.2.0",
     "json-loader": "^0.5.3",
     "karma": "^1.7.0",
     "karma-chrome-launcher": "^0.2.3",
@@ -112,7 +112,7 @@
     "karma-sourcemap-loader": "^0.3.7",
     "karma-spec-reporter": "0.0.31",
     "karma-summary-reporter": "^1.3.3",
-    "karma-webpack": "^1.7.0",
+    "karma-webpack": "^v4.0.0-beta.0",
     "matrix-mock-request": "^1.2.0",
     "matrix-react-test-utils": "^0.2.0",
     "minimist": "^1.2.0",
@@ -120,19 +120,20 @@
     "mocha": "^2.4.5",
     "parallelshell": "^3.0.2",
     "postcss-extend": "^1.0.5",
-    "postcss-import": "^9.0.0",
-    "postcss-loader": "^1.2.2",
-    "postcss-mixins": "^5.4.1",
-    "postcss-nested": "^1.0.0",
-    "postcss-scss": "^0.4.0",
-    "postcss-simple-vars": "^3.0.0",
+    "postcss-import": "^11.1.0",
+    "postcss-loader": "^2.1.4",
+    "postcss-mixins": "^6.2.0",
+    "postcss-nested": "^3.0.0",
+    "postcss-scss": "^1.0.5",
+    "postcss-simple-vars": "^4.1.0",
     "postcss-strip-inline-comments": "^0.1.5",
     "react-addons-perf": "^15.4.0",
     "react-addons-test-utils": "^15.6.0",
     "rimraf": "^2.4.3",
     "source-map-loader": "^0.2.3",
-    "webpack": "^1.12.14",
-    "webpack-dev-server": "^1.16.2"
+    "webpack": "^4.6.0",
+    "webpack-cli": "^2.0.15",
+    "webpack-dev-server": "^3.1.3"
   },
   "optionalDependencies": {
     "olm": "https://matrix.org/packages/npm/olm/olm-2.2.1.tgz"
diff --git a/src/vector/index.html b/src/vector/index.html
index 91d28642c9..dad179a7ba 100644
--- a/src/vector/index.html
+++ b/src/vector/index.html
@@ -37,6 +37,14 @@
     <section id="matrixchat" style="height: 100%;"></section>
     <noscript>Sorry, Riot requires JavaScript to be enabled.</noscript> <!-- TODO: Translate this? -->
     <% for (var i=0; i < htmlWebpackPlugin.files.js.length; i++) {
+        if (_.endsWith(htmlWebpackPlugin.files.js[i], 'olm.js')) {
+            var array = htmlWebpackPlugin.files.js;
+            htmlWebpackPlugin.files.js.unshift(htmlWebpackPlugin.files.js[i]);
+            htmlWebpackPlugin.files.js.splice(i, 1);
+        }
+       }
+
+       for (var i=0; i < htmlWebpackPlugin.files.js.length; i++) {
         // Not a particularly graceful way of not putting the indexeddb worker script
         // into the main page
         if (_.endsWith(htmlWebpackPlugin.files.js[i], 'indexeddb-worker.js')) {
diff --git a/webpack.config.js b/webpack.config.js
index d82d4bcc89..c8482a84de 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -26,15 +26,16 @@ module.exports = {
         "theme-status": "./res/themes/status/css/status.scss",
     },
     module: {
-        preLoaders: [
-            { test: /\.js$/, loader: "source-map-loader" },
-        ],
-        loaders: [
-            { test: /\.json$/, loader: "json" },
-            { test: /\.js$/, loader: "babel", include: path.resolve('./src') },
+        rules: [
+            { enforce: 'pre', test: /\.js$/, use: "source-map-loader", exclude: /node_modules/, },
+            { test: /\.js$/, use: "babel-loader", include: path.resolve(__dirname, 'src') },
             {
                 test: /\.scss$/,
-
+                include: [
+                    path.resolve(__dirname, 'res/themes/status/css/'),
+                    path.resolve(__dirname, 'node_modules/matrix-react-sdk/res/themes/light/css/'),
+                    path.resolve(__dirname, 'node_modules/matrix-react-sdk/res/themes/dark/css/'),
+                ],
                 // 1. postcss-loader turns the SCSS into normal CSS.
                 // 2. css-raw-loader turns the CSS into a javascript module
                 //    whose default export is a string containing the CSS.
@@ -42,13 +43,27 @@ module.exports = {
                 //    would also drag in the imgs and fonts that our CSS refers to
                 //    as webpack inputs.)
                 // 3. ExtractTextPlugin turns that string into a separate asset.
-                loader: ExtractTextPlugin.extract("css-raw-loader!postcss-loader?config=postcss.config.js"),
+                use: ExtractTextPlugin.extract({
+                    use: [
+                        "css-raw-loader",
+                        "postcss-loader"
+                    ],
+                }),
             },
             {
                 // this works similarly to the scss case, without postcss.
                 test: /\.css$/,
-                loader: ExtractTextPlugin.extract("css-raw-loader"),
+                include: [
+                    path.resolve(__dirname, "node_modules/matrix-react-sdk/node_modules/highlight.js/styles"),
+                    path.resolve(__dirname, "node_modules/matrix-react-sdk/node_modules/draft-js/dist"),
+                    path.resolve(__dirname, "node_modules/matrix-react-sdk/node_modules/gfm.css"),
+                    path.resolve(__dirname, "node_modules/matrix-react-sdk/node_modules/gemini-scrollbar/"),
+                ],
+                use: ExtractTextPlugin.extract({
+                    use: "css-raw-loader"
+                }),
             },
+
         ],
         noParse: [
             // for cross platform compatibility use [\\\/] as the path separator