diff --git a/.travis.yml b/.travis.yml
index 3b201c1e..bc3fce38 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,18 +11,25 @@ sudo: required
 language: node_js
 node_js:
     # make sure we work with a range of node versions.
+    # As of the time of writing:
+    #  - 4.x is still in LTS (until April 2018), but some of our deps (notably
+    #    extract-zip) don't work with it
+    #  - 5.x has been EOLed for nearly a year.
+    #  - 6.x is the active 'LTS' version
+    #  - 7.x is no longer supported
+    #  - 8.x is the current 'current' version (until October 2017)
     #
-    # Current status of node versions: https://github.com/nodejs/LTS/
-    # We don't work with node 6 because it doesn't support package-lock
-    # files which we need to avoid the broken version of base-x
-    - 8
-    - 10
+    # see: https://github.com/nodejs/LTS/
+    #
+    # anything before 6.3 ships with npm 3.9 or earlier, which had problems
+    # with symlinks in node_modules (see
+    # https://github.com/npm/npm/releases/tag/v3.10.0 'FIXES AND REFACTORING').
+    - 6.3
+    - 6
+    - 7
 addons:
     chrome: stable
 install:
     # clone the deps with depth 1: we know we will only ever need that one
     # commit.
-    - npm install && scripts/fetch-develop.deps.sh --depth 1
-script:
-    - npm run test
-    - npm run lint
+    - scripts/fetch-develop.deps.sh --depth 1 && npm install
diff --git a/package-lock.json b/package-lock.json
index ab504339..d21cf33f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -46,62 +46,6 @@
         "@babel/highlight": "^7.0.0"
       }
     },
-    "@babel/generator": {
-      "version": "7.0.0-beta.44",
-      "resolved": "http://registry.npmjs.org/@babel/generator/-/generator-7.0.0-beta.44.tgz",
-      "integrity": "sha512-5xVb7hlhjGcdkKpMXgicAVgx8syK5VJz193k0i/0sLP6DzE6lRrU1K3B/rFefgdo9LPGMAOOOAWW4jycj07ShQ==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "7.0.0-beta.44",
-        "jsesc": "^2.5.1",
-        "lodash": "^4.2.0",
-        "source-map": "^0.5.0",
-        "trim-right": "^1.0.1"
-      },
-      "dependencies": {
-        "jsesc": {
-          "version": "2.5.1",
-          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz",
-          "integrity": "sha1-5CGiqOINawgZ3yiQj3glJrlt0f4=",
-          "dev": true
-        },
-        "source-map": {
-          "version": "0.5.7",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
-          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
-          "dev": true
-        }
-      }
-    },
-    "@babel/helper-function-name": {
-      "version": "7.0.0-beta.44",
-      "resolved": "http://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.44.tgz",
-      "integrity": "sha512-MHRG2qZMKMFaBavX0LWpfZ2e+hLloT++N7rfM3DYOMUOGCD8cVjqZpwiL8a0bOX3IYcQev1ruciT0gdFFRTxzg==",
-      "dev": true,
-      "requires": {
-        "@babel/helper-get-function-arity": "7.0.0-beta.44",
-        "@babel/template": "7.0.0-beta.44",
-        "@babel/types": "7.0.0-beta.44"
-      }
-    },
-    "@babel/helper-get-function-arity": {
-      "version": "7.0.0-beta.44",
-      "resolved": "http://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.44.tgz",
-      "integrity": "sha512-w0YjWVwrM2HwP6/H3sEgrSQdkCaxppqFeJtAnB23pRiJB5E/O9Yp7JAAeWBl+gGEgmBFinnTyOv2RN7rcSmMiw==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "7.0.0-beta.44"
-      }
-    },
-    "@babel/helper-split-export-declaration": {
-      "version": "7.0.0-beta.44",
-      "resolved": "http://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0-beta.44.tgz",
-      "integrity": "sha512-aQ7QowtkgKKzPGf0j6u77kBMdUFVBKNHw2p/3HX/POt5/oz8ec5cs0GwlgM8Hz7ui5EwJnzyfRmkNF1Nx1N7aA==",
-      "dev": true,
-      "requires": {
-        "@babel/types": "7.0.0-beta.44"
-      }
-    },
     "@babel/highlight": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
@@ -128,129 +72,6 @@
         }
       }
     },
-    "@babel/template": {
-      "version": "7.0.0-beta.44",
-      "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.44.tgz",
-      "integrity": "sha512-w750Sloq0UNifLx1rUqwfbnC6uSUk0mfwwgGRfdLiaUzfAOiH0tHJE6ILQIUi3KYkjiCDTskoIsnfqZvWLBDng==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "7.0.0-beta.44",
-        "@babel/types": "7.0.0-beta.44",
-        "babylon": "7.0.0-beta.44",
-        "lodash": "^4.2.0"
-      },
-      "dependencies": {
-        "@babel/code-frame": {
-          "version": "7.0.0-beta.44",
-          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz",
-          "integrity": "sha512-cuAuTTIQ9RqcFRJ/Y8PvTh+paepNcaGxwQwjIDRWPXmzzyAeCO4KqS9ikMvq0MCbRk6GlYKwfzStrcP3/jSL8g==",
-          "dev": true,
-          "requires": {
-            "@babel/highlight": "7.0.0-beta.44"
-          }
-        },
-        "@babel/highlight": {
-          "version": "7.0.0-beta.44",
-          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.44.tgz",
-          "integrity": "sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ==",
-          "dev": true,
-          "requires": {
-            "chalk": "^2.0.0",
-            "esutils": "^2.0.2",
-            "js-tokens": "^3.0.0"
-          }
-        },
-        "babylon": {
-          "version": "7.0.0-beta.44",
-          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz",
-          "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==",
-          "dev": true
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
-          "dev": true
-        }
-      }
-    },
-    "@babel/traverse": {
-      "version": "7.0.0-beta.44",
-      "resolved": "http://registry.npmjs.org/@babel/traverse/-/traverse-7.0.0-beta.44.tgz",
-      "integrity": "sha512-UHuDz8ukQkJCDASKHf+oDt3FVUzFd+QYfuBIsiNu/4+/ix6pP/C+uQZJ6K1oEfbCMv/IKWbgDEh7fcsnIE5AtA==",
-      "dev": true,
-      "requires": {
-        "@babel/code-frame": "7.0.0-beta.44",
-        "@babel/generator": "7.0.0-beta.44",
-        "@babel/helper-function-name": "7.0.0-beta.44",
-        "@babel/helper-split-export-declaration": "7.0.0-beta.44",
-        "@babel/types": "7.0.0-beta.44",
-        "babylon": "7.0.0-beta.44",
-        "debug": "^3.1.0",
-        "globals": "^11.1.0",
-        "invariant": "^2.2.0",
-        "lodash": "^4.2.0"
-      },
-      "dependencies": {
-        "@babel/code-frame": {
-          "version": "7.0.0-beta.44",
-          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz",
-          "integrity": "sha512-cuAuTTIQ9RqcFRJ/Y8PvTh+paepNcaGxwQwjIDRWPXmzzyAeCO4KqS9ikMvq0MCbRk6GlYKwfzStrcP3/jSL8g==",
-          "dev": true,
-          "requires": {
-            "@babel/highlight": "7.0.0-beta.44"
-          }
-        },
-        "@babel/highlight": {
-          "version": "7.0.0-beta.44",
-          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.44.tgz",
-          "integrity": "sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ==",
-          "dev": true,
-          "requires": {
-            "chalk": "^2.0.0",
-            "esutils": "^2.0.2",
-            "js-tokens": "^3.0.0"
-          }
-        },
-        "babylon": {
-          "version": "7.0.0-beta.44",
-          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz",
-          "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==",
-          "dev": true
-        },
-        "globals": {
-          "version": "11.8.0",
-          "resolved": "https://registry.npmjs.org/globals/-/globals-11.8.0.tgz",
-          "integrity": "sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA==",
-          "dev": true
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
-          "dev": true
-        }
-      }
-    },
-    "@babel/types": {
-      "version": "7.0.0-beta.44",
-      "resolved": "http://registry.npmjs.org/@babel/types/-/types-7.0.0-beta.44.tgz",
-      "integrity": "sha512-5eTV4WRmqbaFM3v9gHAIljEQJU4Ssc6fxL61JN+Oe2ga/BwyjzjamwkCVVAQjHGuAX8i0BWo42dshL8eO5KfLQ==",
-      "dev": true,
-      "requires": {
-        "esutils": "^2.0.2",
-        "lodash": "^4.2.0",
-        "to-fast-properties": "^2.0.0"
-      },
-      "dependencies": {
-        "to-fast-properties": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
-          "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
-          "dev": true
-        }
-      }
-    },
     "@webassemblyjs/ast": {
       "version": "1.7.10",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.10.tgz",
@@ -1187,51 +1008,16 @@
       }
     },
     "babel-eslint": {
-      "version": "8.2.6",
-      "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-8.2.6.tgz",
-      "integrity": "sha512-aCdHjhzcILdP8c9lej7hvXKvQieyRt20SF102SIGyY4cUIiw6UaAtK4j2o3dXX74jEmy0TJ0CEhv4fTIM3SzcA==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-6.1.2.tgz",
+      "integrity": "sha1-UpNBn+NnLWZZjTJ9qWlFZ7pqXy8=",
       "dev": true,
       "requires": {
-        "@babel/code-frame": "7.0.0-beta.44",
-        "@babel/traverse": "7.0.0-beta.44",
-        "@babel/types": "7.0.0-beta.44",
-        "babylon": "7.0.0-beta.44",
-        "eslint-scope": "3.7.1",
-        "eslint-visitor-keys": "^1.0.0"
-      },
-      "dependencies": {
-        "@babel/code-frame": {
-          "version": "7.0.0-beta.44",
-          "resolved": "http://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.44.tgz",
-          "integrity": "sha512-cuAuTTIQ9RqcFRJ/Y8PvTh+paepNcaGxwQwjIDRWPXmzzyAeCO4KqS9ikMvq0MCbRk6GlYKwfzStrcP3/jSL8g==",
-          "dev": true,
-          "requires": {
-            "@babel/highlight": "7.0.0-beta.44"
-          }
-        },
-        "@babel/highlight": {
-          "version": "7.0.0-beta.44",
-          "resolved": "http://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.44.tgz",
-          "integrity": "sha512-Il19yJvy7vMFm8AVAh6OZzaFoAd0hbkeMZiX3P5HGD+z7dyI7RzndHB0dg6Urh/VAFfHtpOIzDUSxmY6coyZWQ==",
-          "dev": true,
-          "requires": {
-            "chalk": "^2.0.0",
-            "esutils": "^2.0.2",
-            "js-tokens": "^3.0.0"
-          }
-        },
-        "babylon": {
-          "version": "7.0.0-beta.44",
-          "resolved": "http://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz",
-          "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==",
-          "dev": true
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
-          "dev": true
-        }
+        "babel-traverse": "^6.0.20",
+        "babel-types": "^6.0.19",
+        "babylon": "^6.0.18",
+        "lodash.assign": "^4.0.0",
+        "lodash.pickby": "^4.0.0"
       }
     },
     "babel-generator": {
@@ -1451,7 +1237,7 @@
     },
     "babel-plugin-add-module-exports": {
       "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz",
+      "resolved": "http://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz",
       "integrity": "sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU=",
       "dev": true
     },
@@ -1466,55 +1252,55 @@
     },
     "babel-plugin-syntax-async-functions": {
       "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
+      "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
       "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
       "dev": true
     },
     "babel-plugin-syntax-async-generators": {
       "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz",
+      "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz",
       "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=",
       "dev": true
     },
     "babel-plugin-syntax-class-properties": {
       "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
+      "resolved": "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
       "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=",
       "dev": true
     },
     "babel-plugin-syntax-decorators": {
       "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
+      "resolved": "http://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
       "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=",
       "dev": true
     },
     "babel-plugin-syntax-dynamic-import": {
       "version": "6.18.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
+      "resolved": "http://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
       "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=",
       "dev": true
     },
     "babel-plugin-syntax-exponentiation-operator": {
       "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
+      "resolved": "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
       "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
       "dev": true
     },
     "babel-plugin-syntax-flow": {
       "version": "6.18.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz",
+      "resolved": "http://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz",
       "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=",
       "dev": true
     },
     "babel-plugin-syntax-jsx": {
       "version": "6.18.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+      "resolved": "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
       "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=",
       "dev": true
     },
     "babel-plugin-syntax-object-rest-spread": {
       "version": "6.13.0",
-      "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+      "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
       "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
       "dev": true
     },
@@ -2274,7 +2060,7 @@
     },
     "blob": {
       "version": "0.0.4",
-      "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
+      "resolved": "http://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
       "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=",
       "dev": true
     },
@@ -4100,7 +3886,7 @@
     },
     "css-select": {
       "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
+      "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
       "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
       "dev": true,
       "requires": {
@@ -4441,7 +4227,7 @@
       "dependencies": {
         "domelementtype": {
           "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
+          "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
           "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs="
         }
       }
@@ -4454,7 +4240,7 @@
     },
     "domelementtype": {
       "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
+      "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
       "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI="
     },
     "domhandler": {
@@ -4507,7 +4293,7 @@
     },
     "duplexer": {
       "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+      "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
       "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
       "dev": true
     },
@@ -4813,7 +4599,7 @@
         },
         "ms": {
           "version": "0.7.2",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+          "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
           "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
           "dev": true
         }
@@ -4951,7 +4737,7 @@
         },
         "ms": {
           "version": "0.7.2",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+          "resolved": "http://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
           "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
           "dev": true
         },
@@ -5044,7 +4830,7 @@
     },
     "emojione": {
       "version": "2.2.7",
-      "resolved": "https://registry.npmjs.org/emojione/-/emojione-2.2.7.tgz",
+      "resolved": "http://registry.npmjs.org/emojione/-/emojione-2.2.7.tgz",
       "integrity": "sha1-RkV89rmy+NoTroouTlR94G7hXpY="
     },
     "emojis-list": {
@@ -5299,16 +5085,6 @@
             "esutils": "^2.0.2"
           }
         },
-        "eslint-scope": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz",
-          "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==",
-          "dev": true,
-          "requires": {
-            "esrecurse": "^4.1.0",
-            "estraverse": "^4.1.1"
-          }
-        },
         "glob": {
           "version": "7.1.3",
           "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
@@ -5342,7 +5118,7 @@
     },
     "eslint-config-google": {
       "version": "0.7.1",
-      "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.7.1.tgz",
+      "resolved": "http://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.7.1.tgz",
       "integrity": "sha1-VZj4SY6eB4Qg80uASVuNlZ9lH7I=",
       "dev": true
     },
@@ -5386,9 +5162,9 @@
       }
     },
     "eslint-scope": {
-      "version": "3.7.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
-      "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz",
+      "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==",
       "dev": true,
       "requires": {
         "esrecurse": "^4.1.0",
@@ -5582,7 +5358,7 @@
     },
     "expect": {
       "version": "1.20.2",
-      "resolved": "https://registry.npmjs.org/expect/-/expect-1.20.2.tgz",
+      "resolved": "http://registry.npmjs.org/expect/-/expect-1.20.2.tgz",
       "integrity": "sha1-1Fj+TFYAQDa64yMkFqP2Nh8E+WU=",
       "dev": true,
       "requires": {
@@ -5798,7 +5574,7 @@
       "dependencies": {
         "core-js": {
           "version": "1.2.7",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
+          "resolved": "http://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
           "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
         }
       }
@@ -5987,7 +5763,7 @@
       "dependencies": {
         "core-js": {
           "version": "1.2.7",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
+          "resolved": "http://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
           "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
         },
         "fbjs": {
@@ -6797,7 +6573,7 @@
     },
     "get-stream": {
       "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
       "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
       "dev": true
     },
@@ -7652,7 +7428,7 @@
     },
     "immutable": {
       "version": "3.7.6",
-      "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
+      "resolved": "http://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
       "integrity": "sha1-E7TTyxK++hVIKib+Gy665kAHHks="
     },
     "import-cwd": {
@@ -7941,7 +7717,7 @@
     },
     "is-builtin-module": {
       "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+      "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
       "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
       "requires": {
         "builtin-modules": "^1.0.0"
@@ -8123,7 +7899,7 @@
     },
     "is-obj": {
       "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+      "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
       "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
       "dev": true
     },
@@ -8390,7 +8166,7 @@
     },
     "json5": {
       "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+      "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
       "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE="
     },
     "jsonfile": {
@@ -8516,7 +8292,7 @@
         },
         "xmlbuilder": {
           "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-3.1.0.tgz",
+          "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-3.1.0.tgz",
           "integrity": "sha1-LIaIjy1OrehQ+jjKf3Ij9yCVFuE=",
           "dev": true,
           "requires": {
@@ -8710,7 +8486,7 @@
     },
     "load-json-file": {
       "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+      "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
       "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
       "requires": {
         "graceful-fs": "^4.1.2",
@@ -8764,6 +8540,12 @@
       "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.11.tgz",
       "integrity": "sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q=="
     },
+    "lodash.assign": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+      "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
+      "dev": true
+    },
     "lodash.clonedeep": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
@@ -8795,6 +8577,12 @@
       "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz",
       "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ=="
     },
+    "lodash.pickby": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz",
+      "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=",
+      "dev": true
+    },
     "lodash.toarray": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
@@ -8935,7 +8723,7 @@
       }
     },
     "matrix-react-sdk": {
-      "version": "github:matrix-org/matrix-react-sdk#0bd1d6b778f9fc89e0f7e75557f8e7acf576be92",
+      "version": "github:matrix-org/matrix-react-sdk#507bfb4b69c9d45ba8e1165e8865b0479fcb6d7c",
       "from": "github:matrix-org/matrix-react-sdk#develop",
       "requires": {
         "babel-runtime": "^6.26.0",
@@ -9056,7 +8844,7 @@
     },
     "media-typer": {
       "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
       "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
       "dev": true
     },
@@ -9202,7 +8990,7 @@
     },
     "minimist": {
       "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+      "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
       "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
     },
     "mississippi": {
@@ -9246,7 +9034,7 @@
     },
     "mkdirp": {
       "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+      "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
       "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
       "requires": {
         "minimist": "0.0.8"
@@ -9254,7 +9042,7 @@
       "dependencies": {
         "minimist": {
           "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+          "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
           "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
         }
       }
@@ -9786,7 +9574,7 @@
       "dependencies": {
         "minimist": {
           "version": "0.0.10",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+          "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
           "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
         }
       }
@@ -9836,7 +9624,7 @@
     },
     "os-locale": {
       "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+      "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
       "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
       "requires": {
         "lcid": "^1.0.0"
@@ -10120,7 +9908,7 @@
     },
     "pify": {
       "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
       "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
     },
     "pinkie": {
@@ -10199,7 +9987,7 @@
       "dependencies": {
         "async": {
           "version": "1.5.2",
-          "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+          "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
           "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
           "dev": true
         },
@@ -10309,7 +10097,7 @@
     },
     "postcss-import": {
       "version": "11.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.1.0.tgz",
+      "resolved": "http://registry.npmjs.org/postcss-import/-/postcss-import-11.1.0.tgz",
       "integrity": "sha512-5l327iI75POonjxkXgdRCUS+AlzAdBx4pOvMEhTKTCjb1p8IEeVR9yx3cPbmN7LIWJLbfnIXxAhoB4jpD0c/Cw==",
       "dev": true,
       "requires": {
@@ -11450,7 +11238,7 @@
         },
         "htmlparser2": {
           "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz",
+          "resolved": "http://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz",
           "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=",
           "dev": true,
           "requires": {
@@ -11468,7 +11256,7 @@
         },
         "readable-stream": {
           "version": "1.0.34",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+          "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
           "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
           "dev": true,
           "requires": {
@@ -12752,7 +12540,7 @@
     },
     "strip-ansi": {
       "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
       "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
       "requires": {
         "ansi-regex": "^2.0.0"
@@ -12959,7 +12747,7 @@
     },
     "through": {
       "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
       "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
       "dev": true
     },
@@ -13260,7 +13048,7 @@
     },
     "underscore.string": {
       "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz",
+      "resolved": "http://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz",
       "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs="
     },
     "union-value": {
@@ -13714,16 +13502,6 @@
             "ms": "2.0.0"
           }
         },
-        "eslint-scope": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz",
-          "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==",
-          "dev": true,
-          "requires": {
-            "esrecurse": "^4.1.0",
-            "estraverse": "^4.1.1"
-          }
-        },
         "expand-brackets": {
           "version": "2.1.4",
           "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
@@ -14289,7 +14067,7 @@
           "dependencies": {
             "pify": {
               "version": "2.3.0",
-              "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+              "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
               "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
               "dev": true
             }
@@ -14554,7 +14332,7 @@
     },
     "wrap-ansi": {
       "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+      "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
       "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
       "requires": {
         "string-width": "^1.0.1",
diff --git a/package.json b/package.json
index 233b5b86..69142994 100644
--- a/package.json
+++ b/package.json
@@ -84,7 +84,7 @@
     "autoprefixer": "^6.6.0",
     "babel-cli": "^6.26.0",
     "babel-core": "^6.26.3",
-    "babel-eslint": "^8.1.1",
+    "babel-eslint": "^6.1.2",
     "babel-loader": "^7.1.5",
     "babel-plugin-add-module-exports": "^0.2.1",
     "babel-plugin-transform-async-to-bluebird": "^1.1.1",
diff --git a/src/components/structures/VectorHomePage.js b/src/components/structures/VectorHomePage.js
index a2e5fe05..7f741303 100644
--- a/src/components/structures/VectorHomePage.js
+++ b/src/components/structures/VectorHomePage.js
@@ -17,6 +17,7 @@ limitations under the License.
 
 'use strict';
 
+import React from 'react';
 import HomePage from 'matrix-react-sdk/lib/components/structures/HomePage';
 import sanitizeHtml from 'sanitize-html';
 import { _t } from 'matrix-react-sdk/lib/languageHandler';
diff --git a/src/components/views/login/VectorCustomServerDialog.js b/src/components/views/login/VectorCustomServerDialog.js
index c60ff6da..8395f139 100644
--- a/src/components/views/login/VectorCustomServerDialog.js
+++ b/src/components/views/login/VectorCustomServerDialog.js
@@ -15,8 +15,8 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-const React = require("react");
-const sanitizeHtml = require("sanitize-html");
+var React = require("react");
+var sanitizeHtml = require("sanitize-html");
 import { _t } from 'matrix-react-sdk/lib/languageHandler';
 
 module.exports = React.createClass({
@@ -47,5 +47,5 @@ module.exports = React.createClass({
                 </div>
             </div>
         );
-    },
+    }
 });
diff --git a/src/components/views/login/VectorLoginFooter.js b/src/components/views/login/VectorLoginFooter.js
index 5fa42360..26e01c06 100644
--- a/src/components/views/login/VectorLoginFooter.js
+++ b/src/components/views/login/VectorLoginFooter.js
@@ -16,7 +16,7 @@ limitations under the License.
 
 'use strict';
 
-const React = require('react');
+var React = require('react');
 import { _t } from 'matrix-react-sdk/lib/languageHandler';
 import SettingsStore from 'matrix-react-sdk/lib/settings/SettingsStore';
 
@@ -29,8 +29,8 @@ module.exports = React.createClass({
     render: function() {
         // FIXME: replace this with a proper Status skin
         // ...except then we wouldn't be able to switch to the Status theme at runtime.
-        if (SettingsStore.getValue("theme") === 'status') return <div />;
-
+        if (SettingsStore.getValue("theme") === 'status') return <div/>;
+        
         return (
             <div className="mx_Login_links">
                 <a href="https://medium.com/@RiotChat">blog</a>&nbsp;&nbsp;&middot;&nbsp;&nbsp;
@@ -39,5 +39,5 @@ module.exports = React.createClass({
                 <a href="https://matrix.org">{ _t('powered by Matrix') }</a>
             </div>
         );
-    },
+    }
 });
diff --git a/src/components/views/login/VectorLoginHeader.js b/src/components/views/login/VectorLoginHeader.js
index babd90d6..d0ee7934 100644
--- a/src/components/views/login/VectorLoginHeader.js
+++ b/src/components/views/login/VectorLoginHeader.js
@@ -35,9 +35,9 @@ module.exports = React.createClass({
         return (
             <div className="mx_Login_header">
                 <div className="mx_Login_logo">
-                    <img src={this.props.icon || DEFAULT_LOGO_URI} alt="Riot" />
+                    <img src={this.props.icon || DEFAULT_LOGO_URI} alt="Riot"/>
                 </div>
             </div>
         );
-    },
+    }
 });
diff --git a/src/vector/index.js b/src/vector/index.js
index 14bda5b5..b25d08c3 100644
--- a/src/vector/index.js
+++ b/src/vector/index.js
@@ -34,6 +34,7 @@ if (process.env.NODE_ENV !== 'production') {
     global.Perf = require('react-addons-perf');
 }
 
+import RunModernizrTests from './modernizr'; // this side-effects a global
 import ReactDOM from 'react-dom';
 import sdk from 'matrix-react-sdk';
 import PlatformPeg from 'matrix-react-sdk/lib/PlatformPeg';
@@ -42,6 +43,8 @@ import VectorConferenceHandler from 'matrix-react-sdk/lib/VectorConferenceHandle
 import Promise from 'bluebird';
 import request from 'browser-request';
 import * as languageHandler from 'matrix-react-sdk/lib/languageHandler';
+// Also import _t directly so we can call it just `_t` as this is what gen-i18n.js expects
+import { _t } from 'matrix-react-sdk/lib/languageHandler';
 
 import url from 'url';
 
@@ -49,7 +52,7 @@ import {parseQs, parseQsFromFragment} from './url_utils';
 import Platform from './platform';
 
 import MatrixClientPeg from 'matrix-react-sdk/lib/MatrixClientPeg';
-import SettingsStore from "matrix-react-sdk/lib/settings/SettingsStore";
+import SettingsStore, {SettingLevel} from "matrix-react-sdk/lib/settings/SettingsStore";
 import Tinter from 'matrix-react-sdk/lib/Tinter';
 import SdkConfig from "matrix-react-sdk/lib/SdkConfig";
 
@@ -70,12 +73,12 @@ function checkBrowserFeatures(featureList) {
         console.error("Cannot check features - Modernizr global is missing.");
         return false;
     }
-    let featureComplete = true;
-    for (let i = 0; i < featureList.length; i++) {
+    var featureComplete = true;
+    for (var i = 0; i < featureList.length; i++) {
         if (window.Modernizr[featureList[i]] === undefined) {
             console.error(
                 "Looked for feature '%s' but Modernizr has no results for this. " +
-                "Has it been configured correctly?", featureList[i],
+                "Has it been configured correctly?", featureList[i]
             );
             return false;
         }
@@ -96,7 +99,7 @@ function getScreenFromLocation(location) {
     return {
         screen: fragparts.location.substring(1),
         params: fragparts.params,
-    };
+    }
 }
 
 // Here, we do some crude URL analysis to allow
@@ -121,10 +124,10 @@ function onHashChange(ev) {
 // so a web page can update the URL bar appropriately.
 function onNewScreen(screen) {
     console.log("newscreen "+screen);
-    const hash = '#/' + screen;
+    var hash = '#/' + screen;
     lastLocationHashSet = hash;
     window.location.hash = hash;
-}
+};
 
 // We use this to work out what URL the SDK should
 // pass through when registering to allow the user to
@@ -161,7 +164,7 @@ function makeRegistrationUrl(params) {
     return url;
 }
 
-export function getConfig(configJsonFilename) {
+function getConfig(configJsonFilename) {
     return new Promise(function(resolve, reject) {
         request(
             { method: "GET", url: configJsonFilename },
@@ -197,9 +200,9 @@ function onTokenLoginCompleted() {
     // if we did a token login, we're now left with the token, hs and is
     // url as query params in the url; a little nasty but let's redirect to
     // clear them.
-    const parsedUrl = url.parse(window.location.href);
+    var parsedUrl = url.parse(window.location.href);
     parsedUrl.search = "";
-    const formatted = url.format(parsedUrl);
+    var formatted = url.format(parsedUrl);
     console.log("Redirecting to " + formatted + " to drop loginToken " +
                 "from queryparams");
     window.location.href = formatted;
@@ -253,6 +256,7 @@ async function loadApp() {
     }
 
     // as quickly as we possibly can, set a default theme...
+    const styleElements = Object.create(null);
     let a;
     const theme = SettingsStore.getValue("theme");
     for (let i = 0; (a = document.getElementsByTagName("link")[i]); i++) {
@@ -276,7 +280,7 @@ async function loadApp() {
                 // in case it is the first time loading Riot.
                 // `InstallTrigger` is a Object which only exists on Firefox
                 // (it is used for their Plugins) and can be used as a
-                // feature check.
+                // feature check. 
                 // Firefox loads css always before js. This is why we dont use
                 // onload or it's EventListener as thoose will never trigger.
                 if (typeof InstallTrigger !== 'undefined') {
@@ -328,19 +332,19 @@ async function loadApp() {
                 initialScreenAfterLogin={getScreenFromLocation(window.location)}
                 defaultDeviceDisplayName={platform.getDefaultDeviceDisplayName()}
             />,
-            document.getElementById('matrixchat'),
+            document.getElementById('matrixchat')
         );
     } else {
         console.error("Browser is missing required features.");
         // take to a different landing page to AWOOOOOGA at the user
-        const CompatibilityPage = sdk.getComponent("structures.CompatibilityPage");
+        var CompatibilityPage = sdk.getComponent("structures.CompatibilityPage");
         window.matrixChat = ReactDOM.render(
             <CompatibilityPage onAccept={function() {
                 if (window.localStorage) window.localStorage.setItem('mx_accepts_unsupported_browser', true);
                 console.log("User accepts the compatibility risks.");
                 loadApp();
             }} />,
-            document.getElementById('matrixchat'),
+            document.getElementById('matrixchat')
         );
     }
 }
diff --git a/src/vector/indexeddb-worker.js b/src/vector/indexeddb-worker.js
index ff0d8f79..2e94509a 100644
--- a/src/vector/indexeddb-worker.js
+++ b/src/vector/indexeddb-worker.js
@@ -18,4 +18,4 @@ import {IndexedDBStoreWorker} from 'matrix-js-sdk/lib/indexeddb-worker.js';
 
 const remoteWorker = new IndexedDBStoreWorker(postMessage);
 
-export const onmessage = remoteWorker.onMessage;
+onmessage = remoteWorker.onMessage;
diff --git a/src/vector/platform/ElectronPlatform.js b/src/vector/platform/ElectronPlatform.js
index 8b384b20..5ced2a2a 100644
--- a/src/vector/platform/ElectronPlatform.js
+++ b/src/vector/platform/ElectronPlatform.js
@@ -27,7 +27,7 @@ import rageshake from 'matrix-react-sdk/lib/rageshake/rageshake';
 remote.autoUpdater.on('update-downloaded', onUpdateDownloaded);
 
 // try to flush the rageshake logs to indexeddb before quit.
-ipcRenderer.on('before-quit', function() {
+ipcRenderer.on('before-quit', function () {
     console.log('riot-desktop closing');
     rageshake.flush();
 });
diff --git a/src/vector/platform/VectorBasePlatform.js b/src/vector/platform/VectorBasePlatform.js
index 16b9d178..4bf300a5 100644
--- a/src/vector/platform/VectorBasePlatform.js
+++ b/src/vector/platform/VectorBasePlatform.js
@@ -60,8 +60,8 @@ export default class VectorBasePlatform extends BasePlatform {
             // This needs to be in in a try block as it will throw
             // if there are more than 100 badge count changes in
             // its internal queue
-            let bgColor = "#d00";
-            let notif = this.notificationCount;
+            let bgColor = "#d00",
+                notif = this.notificationCount;
 
             if (this.errorDidOccur) {
                 notif = notif || "×";
@@ -114,7 +114,7 @@ export default class VectorBasePlatform extends BasePlatform {
         dis.dispatch({
             action: 'check_updates',
             value: false,
-        });
+        })
     }
 
     getUpdateCheckStatusEnum() {
diff --git a/src/vector/platform/WebPlatform.js b/src/vector/platform/WebPlatform.js
index 2955b84a..cfe51346 100644
--- a/src/vector/platform/WebPlatform.js
+++ b/src/vector/platform/WebPlatform.js
@@ -26,7 +26,7 @@ import Promise from 'bluebird';
 import url from 'url';
 import UAParser from 'ua-parser-js';
 
-const POKE_RATE_MS = 10 * 60 * 1000; // 10 min
+var POKE_RATE_MS = 10 * 60 * 1000; // 10 min
 
 export default class WebPlatform extends VectorBasePlatform {
     constructor() {
diff --git a/src/vector/url_utils.js b/src/vector/url_utils.js
index cbaefa0c..cfa8eae1 100644
--- a/src/vector/url_utils.js
+++ b/src/vector/url_utils.js
@@ -23,16 +23,16 @@ import qs from 'querystring';
 export function parseQsFromFragment(location) {
     // if we have a fragment, it will start with '#', which we need to drop.
     // (if we don't, this will return '').
-    const fragment = location.hash.substring(1);
+    var fragment = location.hash.substring(1);
 
     // our fragment may contain a query-param-like section. we need to fish
     // this out *before* URI-decoding because the params may contain ? and &
     // characters which are only URI-encoded once.
-    const hashparts = fragment.split('?');
+    var hashparts = fragment.split('?');
 
-    const result = {
+    var result = {
         location: decodeURIComponent(hashparts[0]),
-        params: {},
+        params: {}
     };
 
     if (hashparts.length > 1) {
diff --git a/test/all-tests.js b/test/all-tests.js
index 156b8542..2ed16932 100644
--- a/test/all-tests.js
+++ b/test/all-tests.js
@@ -6,8 +6,8 @@
 // ideally these unit tests could be run under nodejs rather than in a browser
 // via karma, but having two separate test frameworks in the same project
 // seems confusing
-const unit_tests = require.context('./unit-tests', true, /\.js$/);
+var unit_tests = require.context('./unit-tests', true, /\.js$/);
 unit_tests.keys().forEach(unit_tests);
 
-const app_tests = require.context('./app-tests', true, /\.jsx?$/);
+var app_tests = require.context('./app-tests', true, /\.jsx?$/);
 app_tests.keys().forEach(app_tests);
diff --git a/test/app-tests/joining.js b/test/app-tests/joining.js
index 60bf3fd3..fc380e7d 100644
--- a/test/app-tests/joining.js
+++ b/test/app-tests/joining.js
@@ -21,36 +21,36 @@ import Platform from '../../src/vector/platform';
 
 require('skin-sdk');
 
-const jssdk = require('matrix-js-sdk');
+var jssdk = require('matrix-js-sdk');
 
-const sdk = require('matrix-react-sdk');
-const peg = require('matrix-react-sdk/lib/MatrixClientPeg');
-const dis = require('matrix-react-sdk/lib/dispatcher');
-const PageTypes = require('matrix-react-sdk/lib/PageTypes');
-const MatrixChat = sdk.getComponent('structures.MatrixChat');
-const RoomDirectory = sdk.getComponent('structures.RoomDirectory');
-const RoomPreviewBar = sdk.getComponent('rooms.RoomPreviewBar');
-const RoomView = sdk.getComponent('structures.RoomView');
+var sdk = require('matrix-react-sdk');
+var peg = require('matrix-react-sdk/lib/MatrixClientPeg');
+var dis = require('matrix-react-sdk/lib/dispatcher');
+var PageTypes = require('matrix-react-sdk/lib/PageTypes');
+var MatrixChat = sdk.getComponent('structures.MatrixChat');
+var RoomDirectory = sdk.getComponent('structures.RoomDirectory');
+var RoomPreviewBar = sdk.getComponent('rooms.RoomPreviewBar');
+var RoomView = sdk.getComponent('structures.RoomView');
 
-const React = require('react');
-const ReactDOM = require('react-dom');
-const ReactTestUtils = require('react-addons-test-utils');
-const expect = require('expect');
+var React = require('react');
+var ReactDOM = require('react-dom');
+var ReactTestUtils = require('react-addons-test-utils');
+var expect = require('expect');
 import Promise from 'bluebird';
 
-const test_utils = require('../test-utils');
-const MockHttpBackend = require('matrix-mock-request');
+var test_utils = require('../test-utils');
+var MockHttpBackend = require('matrix-mock-request');
 
-const HS_URL='http://localhost';
-const IS_URL='http://localhost';
-const USER_ID='@me:localhost';
-const ACCESS_TOKEN='access_token';
+var HS_URL='http://localhost';
+var IS_URL='http://localhost';
+var USER_ID='@me:localhost';
+var ACCESS_TOKEN='access_token';
 
-describe('joining a room', function() {
-    describe('over federation', function() {
-        let parentDiv;
-        let httpBackend;
-        let matrixChat;
+describe('joining a room', function () {
+    describe('over federation', function () {
+        var parentDiv;
+        var httpBackend;
+        var matrixChat;
 
         beforeEach(function() {
             test_utils.beforeEach(this);
@@ -72,8 +72,8 @@ describe('joining a room', function() {
         });
 
         it('should not get stuck at a spinner', function() {
-            const ROOM_ALIAS = '#alias:localhost';
-            const ROOM_ID = '!id:localhost';
+            var ROOM_ALIAS = '#alias:localhost';
+            var ROOM_ID = '!id:localhost';
 
             httpBackend.when('GET', '/pushrules').respond(200, {});
             httpBackend.when('POST', '/filter').respond(200, { filter_id: 'fid' });
@@ -90,7 +90,7 @@ describe('joining a room', function() {
 
             PlatformPeg.set(new Platform());
 
-            const mc = (
+            var mc = (
                 <MatrixChat config={{}}
                     makeRegistrationUrl={()=>{throw new Error("unimplemented");}}
                     initialScreenAfterLogin={{
@@ -100,7 +100,7 @@ describe('joining a room', function() {
             );
             matrixChat = ReactDOM.render(mc, parentDiv);
 
-            let roomView;
+            var roomView;
 
             // wait for /sync to happen. This may take some time, as the client
             // has to initialise indexeddb.
@@ -118,11 +118,11 @@ describe('joining a room', function() {
             }).then(() => {
                 console.log(`${Date.now()} App made requests for directory view; switching to a room.`);
 
-                const roomDir = ReactTestUtils.findRenderedComponentWithType(
+                var roomDir = ReactTestUtils.findRenderedComponentWithType(
                     matrixChat, RoomDirectory);
 
                 // enter an alias in the input, and simulate enter
-                const input = ReactTestUtils.findRenderedDOMComponentWithTag(
+                var input = ReactTestUtils.findRenderedDOMComponentWithTag(
                     roomDir, 'input');
                 input.value = ROOM_ALIAS;
                 ReactTestUtils.Simulate.change(input);
diff --git a/test/app-tests/loading.js b/test/app-tests/loading.js
index 676475b6..dab61657 100644
--- a/test/app-tests/loading.js
+++ b/test/app-tests/loading.js
@@ -40,10 +40,10 @@ import * as test_utils from '../test-utils';
 import MockHttpBackend from 'matrix-mock-request';
 import {parseQs, parseQsFromFragment} from '../../src/vector/url_utils';
 
-const DEFAULT_HS_URL='http://my_server';
-const DEFAULT_IS_URL='http://my_is';
+var DEFAULT_HS_URL='http://my_server';
+var DEFAULT_IS_URL='http://my_is';
 
-describe('loading:', function() {
+describe('loading:', function () {
     let parentDiv;
     let httpBackend;
 
@@ -74,7 +74,7 @@ describe('loading:', function() {
         });
     });
 
-    afterEach(async function() {
+    afterEach(async function () {
         console.log(`${Date.now()}: loading: afterEach`);
         if (parentDiv) {
             ReactDOM.unmountComponentAtNode(parentDiv);
@@ -112,12 +112,12 @@ describe('loading:', function() {
             toString: function() { return this.search + this.hash; },
         };
 
-        const tokenLoginCompleteDefer = Promise.defer();
+        let tokenLoginCompleteDefer = Promise.defer();
         tokenLoginCompletePromise = tokenLoginCompleteDefer.promise;
 
         function onNewScreen(screen) {
             console.log(Date.now() + " newscreen "+screen);
-            const hash = '#/' + screen;
+            var hash = '#/' + screen;
             windowLocation.hash = hash;
             console.log(Date.now() + " browser URI now "+ windowLocation);
         }
@@ -129,7 +129,7 @@ describe('loading:', function() {
             return {
                 screen: fragparts.location.substring(1),
                 params: fragparts.params,
-            };
+            }
         }
 
         const MatrixChat = sdk.getComponent('structures.MatrixChat');
@@ -142,7 +142,7 @@ describe('loading:', function() {
 
         PlatformPeg.set(new Platform());
 
-        const params = parseQs(windowLocation);
+        var params = parseQs(windowLocation);
         matrixChat = ReactDOM.render(
             <MatrixChat
                 onNewScreen={onNewScreen}
@@ -153,7 +153,7 @@ describe('loading:', function() {
                 onTokenLoginCompleted={() => tokenLoginCompleteDefer.resolve()}
                 initialScreenAfterLogin={getScreenFromLocation(windowLocation)}
                 makeRegistrationUrl={() => {throw new Error('Not implemented');}}
-            />, parentDiv,
+            />, parentDiv
         );
     }
 
@@ -179,7 +179,7 @@ describe('loading:', function() {
     }
 
     describe("Clean load with no stored credentials:", function() {
-        it('gives a login panel by default', function(done) {
+        it('gives a login panel by default', function (done) {
             loadApp();
 
             Promise.delay(1).then(() => {
@@ -257,6 +257,7 @@ describe('loading:', function() {
                 }
                 return completeLogin(matrixChat);
             }).then(() => {
+
                 // once the sync completes, we should have a room view
                 ReactTestUtils.findRenderedComponentWithType(
                     matrixChat, sdk.getComponent('structures.HomePage'));
@@ -355,7 +356,7 @@ describe('loading:', function() {
                 });
                 return httpBackend.flush();
             }).then(() => {
-                return awaitSyncingSpinner(matrixChat);
+                return awaitSyncingSpinner(matrixChat)
             }).then(() => {
                 // we got a sync spinner - let the sync complete
                 return expectAndAwaitSync();
@@ -379,7 +380,7 @@ describe('loading:', function() {
             it('shows a login view', function() {
                 // we expect a single <Login> component
                 ReactTestUtils.findRenderedComponentWithType(
-                    matrixChat, sdk.getComponent('structures.login.Login'),
+                    matrixChat, sdk.getComponent('structures.login.Login')
                 );
 
                 // the only outstanding request should be a GET /login
@@ -407,7 +408,7 @@ describe('loading:', function() {
     });
 
     describe('Guest auto-registration:', function() {
-        it('shows a home page by default', function(done) {
+        it('shows a home page by default', function (done) {
             loadApp();
 
             Promise.delay(1).then(() => {
@@ -437,7 +438,7 @@ describe('loading:', function() {
             }).done(done, done);
         });
 
-        it('uses the last known homeserver to register with', function(done) {
+        it('uses the last known homeserver to register with', function (done) {
             localStorage.setItem("mx_hs_url", "https://homeserver" );
             localStorage.setItem("mx_is_url", "https://idserver" );
 
@@ -476,7 +477,7 @@ describe('loading:', function() {
 
         it('shows a room view if we followed a room link', function(done) {
             loadApp({
-                uriFragment: "#/room/!room:id",
+                uriFragment: "#/room/!room:id"
             });
             Promise.delay(1).then(() => {
                 // at this point, we're trying to do a guest registration;
@@ -546,7 +547,7 @@ describe('loading:', function() {
 
                 // we expect a single <Login> component
                 ReactTestUtils.findRenderedComponentWithType(
-                    matrixChat, sdk.getComponent('structures.login.Login'),
+                    matrixChat, sdk.getComponent('structures.login.Login')
                 );
             });
 
@@ -579,7 +580,7 @@ describe('loading:', function() {
     });
 
     describe('Token login:', function() {
-        it('logs in successfully', function(done) {
+        it('logs in successfully', function (done) {
             loadApp({
                 queryString: "?loginToken=secretToken&homeserver=https%3A%2F%2Fhomeserver&identityServer=https%3A%2F%2Fidserver",
             });
@@ -657,7 +658,7 @@ describe('loading:', function() {
 
 // assert that we are on the loading page
 function assertAtLoadingSpinner(matrixChat) {
-    const domComponent = ReactDOM.findDOMNode(matrixChat);
+    var domComponent = ReactDOM.findDOMNode(matrixChat);
     expect(domComponent.className).toEqual("mx_MatrixChat_splash");
 
     // just the spinner
@@ -696,12 +697,12 @@ function awaitSyncingSpinner(matrixChat, retryLimit, retryCount) {
 }
 
 function assertAtSyncingSpinner(matrixChat) {
-    const domComponent = ReactDOM.findDOMNode(matrixChat);
+    var domComponent = ReactDOM.findDOMNode(matrixChat);
     expect(domComponent.className).toEqual("mx_MatrixChat_splash");
 
     ReactTestUtils.findRenderedComponentWithType(
         matrixChat, sdk.getComponent('elements.Spinner'));
-    const logoutLink = ReactTestUtils.findRenderedDOMComponentWithTag(
+    var logoutLink = ReactTestUtils.findRenderedDOMComponentWithTag(
         matrixChat, 'a');
     expect(logoutLink.text).toEqual("Logout");
 }
diff --git a/test/skin-sdk.js b/test/skin-sdk.js
index b839df8f..3421d5d0 100644
--- a/test/skin-sdk.js
+++ b/test/skin-sdk.js
@@ -4,5 +4,5 @@
  * Skins the react-sdk with the vector components
  */
 
-const sdk = require('matrix-react-sdk');
+var sdk = require('matrix-react-sdk');
 sdk.loadSkin(require('../src/component-index'));
diff --git a/test/test-utils.js b/test/test-utils.js
index 4e07be14..a5b22feb 100644
--- a/test/test-utils.js
+++ b/test/test-utils.js
@@ -8,7 +8,7 @@ import Promise from 'bluebird';
  * @param {Mocha.Context} context  The test context
  */
 export function beforeEach(context) {
-    const desc = context.currentTest.fullTitle();
+    var desc = context.currentTest.fullTitle();
     console.log();
     console.log(desc);
     console.log(new Array(1 + desc.length).join("="));
@@ -22,7 +22,7 @@ export function beforeEach(context) {
  * returns true if the current environment supports webrtc
  */
 export function browserSupportsWebRTC() {
-    const n = global.window.navigator;
+    var n = global.window.navigator;
     return n.getUserMedia || n.webkitGetUserMedia ||
         n.mozGetUserMedia;
 }