diff --git a/.eslintrc.js b/.eslintrc.js
index 730839944e6422b6e7b0489916bfd42133955d01..1cadfd103fd1910f79fb0e7928b0663b9e6a248a 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -15,6 +15,7 @@ module.exports = {
     "prettier/prettier": "error",
     "prefer-const": "error",
     "no-var": "error",
+    "no-throw-literal": "error",
     // Light console usage is useful but remove debug logs before merging to master.
     "no-console": "off"
   },
diff --git a/src/activators/pressedmove.js b/src/activators/pressedmove.js
index c035383186e0997908be2eae5868a1a97e546dd4..fb7d7470723246b687049eafeb83d51e84f0e8bd 100644
--- a/src/activators/pressedmove.js
+++ b/src/activators/pressedmove.js
@@ -18,10 +18,10 @@ PressedMove.prototype = {
       this.onActivate(event);
     }
   },
-  onButtonDown: function(event) {
+  onButtonDown: function() {
     this.pressed = true;
   },
-  onButtonUp: function(event) {
+  onButtonUp: function() {
     this.pressed = false;
   },
 
diff --git a/src/activators/shortpress.js b/src/activators/shortpress.js
index 7f47450bef78161554a89569d4a610d7f7691877..fd9b8da0a212dc6acfba55509072d9c46c079305 100644
--- a/src/activators/shortpress.js
+++ b/src/activators/shortpress.js
@@ -16,13 +16,12 @@ function ShortPress(el, button, onActivate) {
 
 ShortPress.prototype = {
   onButtonDown(event) {
-    var self = this;
-    this.pressTimer = window.setTimeout(function() {
-      self.onActivate(event);
+    this.pressTimer = window.setTimeout(() => {
+      this.onActivate(event);
     }, this.timeOut);
   },
 
-  onButtonUp(event) {
+  onButtonUp() {
     clearTimeout(this.pressTimer);
   },
 
diff --git a/src/behaviours/oculus-touch-joystick-dpad4.js b/src/behaviours/oculus-touch-joystick-dpad4.js
index 67d3352338a40d021c1c44cfb36c455205cde8af..bf397ba2fbda2357c7fdf1cfc0310c8aa1ba548c 100644
--- a/src/behaviours/oculus-touch-joystick-dpad4.js
+++ b/src/behaviours/oculus-touch-joystick-dpad4.js
@@ -1,4 +1,4 @@
-import { angleTo4Direction, angleTo8Direction } from "../utils/dpad";
+import { angleTo4Direction } from "../utils/dpad";
 
 // @TODO specify 4 or 8 direction
 function oculus_touch_joystick_dpad4(el, outputPrefix) {
diff --git a/src/behaviours/vive-trackpad-dpad4.js b/src/behaviours/vive-trackpad-dpad4.js
index cf477635f7747434f12dedcc69009c58824afad1..99bdf8873d4cbcce3541691e6073af71c153db2b 100644
--- a/src/behaviours/vive-trackpad-dpad4.js
+++ b/src/behaviours/vive-trackpad-dpad4.js
@@ -1,4 +1,4 @@
-import { angleTo4Direction, angleTo8Direction } from "../utils/dpad";
+import { angleTo4Direction } from "../utils/dpad";
 
 function vive_trackpad_dpad4(el, outputPrefix) {
   this.outputPrefix = outputPrefix;
@@ -16,10 +16,10 @@ function vive_trackpad_dpad4(el, outputPrefix) {
 }
 
 vive_trackpad_dpad4.prototype = {
-  press: function(_) {
+  press: function() {
     this.pressed = true;
   },
-  unpress: function(_) {
+  unpress: function() {
     this.pressed = false;
   },
   emitDPad4: function(event) {
diff --git a/src/components/character-controller.js b/src/components/character-controller.js
index 20553d36ce9c06ca84806fd5b6adc7350ddf2aaa..1249dff3b0fbb3231bb52bd373e6cd91b7f3a544 100644
--- a/src/components/character-controller.js
+++ b/src/components/character-controller.js
@@ -60,11 +60,11 @@ AFRAME.registerComponent("character-controller", {
     this.angularVelocity = event.detail.value;
   },
 
-  snapRotateLeft: function(event) {
+  snapRotateLeft: function() {
     this.pendingSnapRotationMatrix.copy(this.leftRotationMatrix);
   },
 
-  snapRotateRight: function(event) {
+  snapRotateRight: function() {
     this.pendingSnapRotationMatrix.copy(this.rightRotationMatrix);
   },
 
@@ -79,9 +79,6 @@ AFRAME.registerComponent("character-controller", {
     const rotationInvMatrix = new THREE.Matrix4();
     const pivotRotationMatrix = new THREE.Matrix4();
     const pivotRotationInvMatrix = new THREE.Matrix4();
-    const position = new THREE.Vector3();
-    const currentPosition = new THREE.Vector3();
-    const movementVector = new THREE.Vector3();
 
     return function(t, dt) {
       const deltaSeconds = dt / 1000;
diff --git a/src/components/haptic-feedback.js b/src/components/haptic-feedback.js
index 1ef413d38939a183c25438694cebaec934d9cf23..35a79cd9555e2864e5c496f671fcb9ddd8831345 100644
--- a/src/components/haptic-feedback.js
+++ b/src/components/haptic-feedback.js
@@ -18,9 +18,9 @@ AFRAME.registerComponent("haptic-feedback", {
   },
 
   getActuator() {
-    return new Promise((resolve, reject) => {
+    return new Promise(resolve => {
       const tryGetActivator = () => {
-        var trackedControls = this.el.components["tracked-controls"];
+        const trackedControls = this.el.components["tracked-controls"];
         if (
           trackedControls &&
           trackedControls.controller &&
@@ -44,7 +44,7 @@ AFRAME.registerComponent("haptic-feedback", {
   },
 
   pulse: function(event) {
-    let { intensity } = event.detail;
+    const { intensity } = event.detail;
     if (!strengthForIntensity[intensity]) {
       console.warn(`Invalid intensity : ${intensity}`);
       return;
diff --git a/src/components/ik-controller.js b/src/components/ik-controller.js
index 0a1990bd8ede46f4e5bbdde5cfced182ed4f5a3d..4fd89465e1d4ce97c24276b5d23d89eda5a25163 100644
--- a/src/components/ik-controller.js
+++ b/src/components/ik-controller.js
@@ -142,7 +142,6 @@ AFRAME.registerComponent("ik-controller", {
       cameraYRotation,
       cameraYQuaternion,
       invHipsQuaternion,
-      headQuaternion,
       leftHand,
       rightHand,
       rootToChest,
diff --git a/src/components/in-world-hud.js b/src/components/in-world-hud.js
index e69cfd7374eaa1ca1972b3cb00784d837dc987b8..2c10aad240d6ee2d21ea8d536751b0fc3785a463 100644
--- a/src/components/in-world-hud.js
+++ b/src/components/in-world-hud.js
@@ -96,7 +96,7 @@ AFRAME.registerComponent("in-world-hud", {
     this.el.sceneEl.removeEventListener("micAudio", this.onAudioFrequencyChange);
   },
 
-  tick: function(t, dt) {
+  tick: function() {
     if (!this.analyser) return;
 
     this.analyser.getByteFrequencyData(this.levels);
diff --git a/src/components/mute-mic.js b/src/components/mute-mic.js
index 272b40e3b41f5d4aa49d7107b6aa41785b8d5596..00729ba1904002a88729e21ed82f69dbb872dda9 100644
--- a/src/components/mute-mic.js
+++ b/src/components/mute-mic.js
@@ -1,6 +1,6 @@
 const bindAllEvents = function(elements, events, f) {
   if (!elements || !elements.length) return;
-  for (var el of elements) {
+  for (const el of elements) {
     events.length &&
       events.forEach(e => {
         el.addEventListener(e, f);
@@ -9,7 +9,7 @@ const bindAllEvents = function(elements, events, f) {
 };
 const unbindAllEvents = function(elements, events, f) {
   if (!elements || !elements.length) return;
-  for (var el of elements) {
+  for (const el of elements) {
     events.length &&
       events.forEach(e => {
         el.removeEventListener(e, f);
diff --git a/src/components/networked-counter.js b/src/components/networked-counter.js
index c13f621fb5ee2cb2863bd8d2a90dc66ba3a13082..9c4fb7105578b49b48d5abe61e4c92193a0aaede 100644
--- a/src/components/networked-counter.js
+++ b/src/components/networked-counter.js
@@ -75,11 +75,11 @@ AFRAME.registerComponent("networked-counter", {
     }
   },
 
-  _onGrabbed: function(id, e) {
+  _onGrabbed: function(id) {
     this._removeTimeout(id);
   },
 
-  _onReleased: function(id, e) {
+  _onReleased: function(id) {
     this._removeTimeout(id);
     this._addTimeout(id);
     this.queue[id].ts = Date.now();
@@ -91,7 +91,6 @@ AFRAME.registerComponent("networked-counter", {
         ts = Number.MAX_VALUE;
       for (const id in this.queue) {
         if (this.queue.hasOwnProperty(id)) {
-          const expiration = this.queue[id].ts + this.data.ttl * 1000;
           if (this.queue[id].ts < ts && !this._isCurrentlyGrabbed(id)) {
             oldest = this.queue[id];
             ts = this.queue[id].ts;
diff --git a/src/components/player-info.js b/src/components/player-info.js
index ac2fc6b55fcdaf0215e26327368c07dd67e88fcc..155a6b82a3752e51e5d3bed3df4d0c98ec9ac929 100644
--- a/src/components/player-info.js
+++ b/src/components/player-info.js
@@ -12,7 +12,7 @@ AFRAME.registerComponent("player-info", {
   pause() {
     this.el.removeEventListener("model-loaded", this.applyProperties);
   },
-  update(oldProps) {
+  update() {
     this.applyProperties();
   },
   applyProperties() {
diff --git a/src/components/super-cursor.js b/src/components/super-cursor.js
index e498a1acc2ad9b99c9131134bd17560bee1af531..28589171658f9d06ed57b4e604d91a73032ea583 100644
--- a/src/components/super-cursor.js
+++ b/src/components/super-cursor.js
@@ -103,7 +103,7 @@ AFRAME.registerComponent("super-cursor", {
     }
   },
 
-  _handleMouseDown: function(e) {
+  _handleMouseDown: function() {
     if (this.isInteractable) {
       const lookControls = this.data.camera.components["look-controls"];
       lookControls.pause();
@@ -115,7 +115,7 @@ AFRAME.registerComponent("super-cursor", {
     this.mousePos.set(e.clientX / window.innerWidth * 2 - 1, -(e.clientY / window.innerHeight) * 2 + 1);
   },
 
-  _handleMouseUp: function(e) {
+  _handleMouseUp: function() {
     const lookControls = this.data.camera.components["look-controls"];
     lookControls.play();
     this.data.cursor.emit("action_release", {});
@@ -125,13 +125,13 @@ AFRAME.registerComponent("super-cursor", {
     if (this.isGrabbing) this.currentDistanceMod += e.deltaY / 10;
   },
 
-  _handleEnterVR: function(e) {
+  _handleEnterVR: function() {
     if (AFRAME.utils.device.checkHeadsetConnected() || AFRAME.utils.device.isMobile()) {
       this._disable();
     }
   },
 
-  _handleExitVR: function(e) {
+  _handleExitVR: function() {
     this._enable();
   },
 
diff --git a/src/components/super-networked-interactable.js b/src/components/super-networked-interactable.js
index 601eebd55c996839f71d6bdce86d49131c22590c..a5baed53dd2f3f5404a81a26150904353434e9e9 100644
--- a/src/components/super-networked-interactable.js
+++ b/src/components/super-networked-interactable.js
@@ -42,7 +42,7 @@ AFRAME.registerComponent("super-networked-interactable", {
     }
   },
 
-  _onOwnershipLost: function(e) {
+  _onOwnershipLost: function() {
     this.el.setAttribute("body", { mass: 0 });
     this.el.emit("grab-end", { hand: this.hand });
     this.hand = null;
diff --git a/src/components/super-spawner.js b/src/components/super-spawner.js
index 7c17c96c45dc17221a4709bdc25b71a349d0867a..bb6762a200eeacf53c29179f95554c7dc8fdab57 100644
--- a/src/components/super-spawner.js
+++ b/src/components/super-spawner.js
@@ -19,7 +19,7 @@ AFRAME.registerComponent("super-spawner", {
   },
 
   remove: function() {
-    for (let entity of this.entities.keys()) {
+    for (const entity of this.entities.keys()) {
       const data = this.entities.get(entity);
       entity.removeEventListener("componentinitialized", data.componentinInitializedListener);
       entity.removeEventListener("bodyloaded", data.bodyLoadedListener);
@@ -60,7 +60,7 @@ AFRAME.registerComponent("super-spawner", {
     }
   },
 
-  _handleBodyLoaded: function(entity, e) {
+  _handleBodyLoaded: function(entity) {
     this.entities.get(entity).bodyLoaded = true;
     this._emitEvents.call(this, entity);
   },
diff --git a/src/components/virtual-gamepad-controls.js b/src/components/virtual-gamepad-controls.js
index d399e38b29765280a677bb23289cdc3e4c2aff6b..d70219bf1e6374fefc6d6daaeb9e8e10bfc27fb8 100644
--- a/src/components/virtual-gamepad-controls.js
+++ b/src/components/virtual-gamepad-controls.js
@@ -1,10 +1,6 @@
 import nipplejs from "nipplejs";
 import styles from "./virtual-gamepad-controls.css";
 
-const THREE = AFRAME.THREE;
-const DEGREES = Math.PI / 180;
-const HALF_PI = Math.PI / 2;
-
 AFRAME.registerComponent("virtual-gamepad-controls", {
   schema: {},
 
diff --git a/src/components/wasd-to-analog2d.js b/src/components/wasd-to-analog2d.js
index a424cb893ab10c29575667f7c68539dd65e90689..35b68026bd121a35bb7f7c139d15423262475b86 100644
--- a/src/components/wasd-to-analog2d.js
+++ b/src/components/wasd-to-analog2d.js
@@ -44,7 +44,7 @@ AFRAME.registerComponent("wasd-to-analog2d", {
     this.keys[key] = down;
   },
 
-  tick: function(t, dt) {
+  tick: function() {
     this.target = [0, 0];
 
     for (const key in this.keys) {
diff --git a/src/components/water.js b/src/components/water.js
index 8dd6463efe3146e02e525fda8f48587d09655dea..b7f176131ea97f6f47fbbb31b27c59e80350b78b 100644
--- a/src/components/water.js
+++ b/src/components/water.js
@@ -17,7 +17,6 @@ function MobileWater(geometry, options) {
 
   options = options || {};
 
-  const clipBias = options.clipBias !== undefined ? options.clipBias : 0.0;
   const time = options.time !== undefined ? options.time : 0.0;
   const normalSampler = options.waterNormals !== undefined ? options.waterNormals : null;
   const sunDirection =
diff --git a/src/elements/a-progressive-asset.js b/src/elements/a-progressive-asset.js
index 8bf922aa17b10ce6eec09baf413e93dcf6d871f1..db51b9b74484043a1f83847cc64d4ccc4bc6554c 100644
--- a/src/elements/a-progressive-asset.js
+++ b/src/elements/a-progressive-asset.js
@@ -33,7 +33,7 @@ AFRAME.registerElement("a-progressive-asset", {
           src = lowSrc;
         }
 
-        this.fileLoader.setResponseType(this.getAttribute("response-type") || inferResponseType(src));
+        this.fileLoader.setResponseType(this.getAttribute("response-type"));
         this.fileLoader.load(
           src,
           function handleOnLoad(response) {
diff --git a/src/react-components/2d-hud.js b/src/react-components/2d-hud.js
index fda3ae06ad0ce63b7b773d5a69f4141b52389c9f..1a2fc6c7091daa3f1371e065e58f5d4d0253bb58 100644
--- a/src/react-components/2d-hud.js
+++ b/src/react-components/2d-hud.js
@@ -1,4 +1,4 @@
-import React, { Component } from "react";
+import React from "react";
 import PropTypes from "prop-types";
 import cx from "classnames";
 
diff --git a/src/react-components/auto-exit-warning.js b/src/react-components/auto-exit-warning.js
index 8663dcca2277d42456511adb212238d3bcdb936f..d8691a85182c7f8bbd3ee9a7472e428df9aa2d3b 100644
--- a/src/react-components/auto-exit-warning.js
+++ b/src/react-components/auto-exit-warning.js
@@ -1,4 +1,4 @@
-import React, { Component } from "react";
+import React from "react";
 import { FormattedMessage } from "react-intl";
 import PropTypes from "prop-types";
 
diff --git a/src/react-components/entry-buttons.js b/src/react-components/entry-buttons.js
index e2754712def40c875e9842a2b27800f90c002f86..8ed8b171d6e7ec08d82d59af2c5314d9353a7910 100644
--- a/src/react-components/entry-buttons.js
+++ b/src/react-components/entry-buttons.js
@@ -1,4 +1,4 @@
-import React, { Component } from "react";
+import React from "react";
 import { FormattedMessage } from "react-intl";
 import PropTypes from "prop-types";
 import MobileDetect from "mobile-detect";
diff --git a/src/react-components/profile-entry-panel.js b/src/react-components/profile-entry-panel.js
index 990add71c4a84571d451fc3d22be8f56454af668..27b7613e261c684a4eca41d70b1256a68ee62cc8 100644
--- a/src/react-components/profile-entry-panel.js
+++ b/src/react-components/profile-entry-panel.js
@@ -7,7 +7,8 @@ class ProfileEntryPanel extends Component {
   static propTypes = {
     store: PropTypes.object,
     messages: PropTypes.object,
-    finished: PropTypes.func
+    finished: PropTypes.func,
+    intl: PropTypes.object
   };
 
   constructor(props) {
diff --git a/src/react-components/profile-info-header.js b/src/react-components/profile-info-header.js
index 6b9e82bb124e931dbf59b0867eaa3e36aae431f2..43ec49291007089d54e1d1a52c7a586e766e5fb4 100644
--- a/src/react-components/profile-info-header.js
+++ b/src/react-components/profile-info-header.js
@@ -1,4 +1,4 @@
-import React, { Component } from "react";
+import React from "react";
 import PropTypes from "prop-types";
 
 export const ProfileInfoHeader = props => (
diff --git a/src/react-components/ui-root.js b/src/react-components/ui-root.js
index bca79ffa35eb0fa2188c557b830aab3eca960b95..1ea5779d5cbd6259888e31b6d174a741305150a9 100644
--- a/src/react-components/ui-root.js
+++ b/src/react-components/ui-root.js
@@ -3,7 +3,6 @@ import PropTypes from "prop-types";
 import classNames from "classnames";
 import { VR_DEVICE_AVAILABILITY } from "../utils/vr-caps-detect";
 import queryString from "query-string";
-import { SCHEMA } from "../storage/store";
 import MobileDetect from "mobile-detect";
 import { IntlProvider, FormattedMessage, addLocaleData } from "react-intl";
 import en from "react-intl/locale-data/en";
@@ -34,13 +33,6 @@ const ENTRY_STEPS = {
   finished: "finished"
 };
 
-const HMD_MIC_REGEXES = [/\Wvive\W/i, /\Wrift\W/i];
-
-async function grantedMicLabels() {
-  const mediaDevices = await navigator.mediaDevices.enumerateDevices();
-  return mediaDevices.filter(d => d.label && d.kind === "audioinput").map(d => d.label);
-}
-
 // This is a list of regexes that match the microphone labels of HMDs.
 //
 // If entering VR mode, and if any of these regexes match an audio device,
@@ -49,13 +41,19 @@ async function grantedMicLabels() {
 //
 // Note that this doesn't have to be exhaustive: if no devices match any regex
 // then we rely upon the user to select the proper mic.
-const VR_DEVICE_MIC_LABEL_REGEXES = [];
+const HMD_MIC_REGEXES = [/\Wvive\W/i, /\Wrift\W/i];
+
+async function grantedMicLabels() {
+  const mediaDevices = await navigator.mediaDevices.enumerateDevices();
+  return mediaDevices.filter(d => d.label && d.kind === "audioinput").map(d => d.label);
+}
 
 const AUTO_EXIT_TIMER_SECONDS = 10;
 
 class UIRoot extends Component {
   static propTypes = {
     enterScene: PropTypes.func,
+    exitScene: PropTypes.func,
     concurrentLoadDetector: PropTypes.object,
     disableAutoExitOnConcurrentLoad: PropTypes.bool,
     forcedVREntryType: PropTypes.string,
@@ -250,32 +248,32 @@ class UIRoot extends Component {
     this.exit();
 
     // Launch via Oculus Browser
-    const qs = queryString.parse(document.location.search);
+    const location = window.location;
+    const qs = queryString.parse(location.search);
     qs.vr_entry_type = "gearvr"; // Auto-choose 'gearvr' after landing in Oculus Browser
 
-    const ovrwebUrl = `ovrweb://${document.location.protocol || "http:"}//${document.location.host}${document.location
-      .pathname || ""}?${queryString.stringify(qs)}#{document.location.hash || ""}`;
+    const ovrwebUrl =
+      `ovrweb://${location.protocol || "http:"}//${location.host}` +
+      `${location.pathname || ""}?${queryString.stringify(qs)}#${location.hash || ""}`;
 
-    document.location = ovrwebUrl;
+    window.location = ovrwebUrl;
   };
 
   enterDaydream = async () => {
-    const loc = document.location;
-
     if (this.state.availableVREntryTypes.daydream == VR_DEVICE_AVAILABILITY.maybe) {
       this.exit();
 
       // We are not in mobile chrome, so launch into chrome via an Intent URL
-      const qs = queryString.parse(document.location.search);
+      const location = window.location;
+      const qs = queryString.parse(location.search);
       qs.vr_entry_type = "daydream"; // Auto-choose 'daydream' after landing in chrome
 
-      const intentUrl = `intent://${document.location.host}${document.location.pathname || ""}?${queryString.stringify(
-        qs
-      )}#Intent;scheme=${(document.location.protocol || "http:").replace(
-        ":",
-        ""
-      )};action=android.intent.action.VIEW;package=com.android.chrome;end;`;
-      document.location = intentUrl;
+      const intentUrl =
+        `intent://${location.host}${location.pathname || ""}?` +
+        `${queryString.stringify(qs)}#Intent;scheme=${(location.protocol || "http:").replace(":", "")};` +
+        `action=android.intent.action.VIEW;package=com.android.chrome;end;`;
+
+      window.location = intentUrl;
     } else {
       await this.performDirectEntryFlow(true);
     }
@@ -324,7 +322,7 @@ class UIRoot extends Component {
     this.setState({ audioTrack: mediaStream.getAudioTracks()[0] });
   };
 
-  setupNewMediaStream = async constraints => {
+  setupNewMediaStream = async () => {
     const mediaStream = new MediaStream();
 
     // we should definitely have an audioTrack at this point.
diff --git a/src/storage/store.js b/src/storage/store.js
index b73825ef3a03c9971a7a9e49d612aee4582abf17..a517bfc5749c53eb9a193298194f7ed7fa0ee56f 100644
--- a/src/storage/store.js
+++ b/src/storage/store.js
@@ -51,15 +51,14 @@ export default class Store extends EventTarget {
 
   update(newState) {
     if (newState.id) {
-      throw "Store id is immutable.";
+      throw new Error("Store id is immutable.");
     }
 
     const finalState = { ...this.state, ...newState };
     const isValid = validator.validate(finalState, SCHEMA).valid;
 
     if (!isValid) {
-      throw `Write of ${JSON.stringify(finalState)} to store failed schema validation.`;
-      return;
+      throw new Error(`Write of ${JSON.stringify(finalState)} to store failed schema validation.`);
     }
 
     localStorage.setItem(LOCAL_STORE_KEY, JSON.stringify(finalState));
diff --git a/src/systems/app-mode.js b/src/systems/app-mode.js
index 421bf48abbab344b877f9805803a7dfe30472336..1ef1c2cd0d7b79c75d0738717558901370320e5b 100644
--- a/src/systems/app-mode.js
+++ b/src/systems/app-mode.js
@@ -188,7 +188,7 @@ AFRAME.registerComponent("vr-mode-toggle-visibility", {
     this.el.sceneEl.removeEventListener("exit-vr", this.updateComponentState);
   },
 
-  updateComponentState(i) {
+  updateComponentState() {
     const inVRMode = this.el.sceneEl.is("vr-mode");
     this.el.setAttribute("visible", inVRMode !== this.data.invert);
   }
@@ -218,7 +218,7 @@ AFRAME.registerComponent("vr-mode-toggle-playing", {
     this.el.sceneEl.removeEventListener("exit-vr", this.updateComponentState);
   },
 
-  updateComponentState(i) {
+  updateComponentState() {
     const componentName = this.id;
     const inVRMode = this.el.sceneEl.is("vr-mode");
     this.el.components[componentName][inVRMode !== this.data.invert ? "play" : "pause"]();
diff --git a/src/systems/personal-space-bubble.js b/src/systems/personal-space-bubble.js
index 563818408f3dc4ea594f5ba2bc2eb10749dca5d2..e696705e138159a67c79e9707fe97bada64a9a58 100644
--- a/src/systems/personal-space-bubble.js
+++ b/src/systems/personal-space-bubble.js
@@ -39,16 +39,16 @@ AFRAME.registerSystem("personal-space-bubble", {
 
   tick() {
     // Update matrix positions once for each space bubble and space invader
-    for (var i = 0; i < this.bubbles.length; i++) {
+    for (let i = 0; i < this.bubbles.length; i++) {
       this.bubbles[i].object3D.updateMatrixWorld(true);
     }
 
-    for (var i = 0; i < this.invaders.length; i++) {
+    for (let i = 0; i < this.invaders.length; i++) {
       this.invaders[i].object3D.updateMatrixWorld(true);
     }
 
     // Loop through all of the space bubbles (usually one)
-    for (var i = 0; i < this.bubbles.length; i++) {
+    for (let i = 0; i < this.bubbles.length; i++) {
       const bubble = this.bubbles[i];
 
       bubblePos.setFromMatrixPosition(bubble.object3D.matrixWorld);
diff --git a/src/utils/dpad.js b/src/utils/dpad.js
index 6f135122e6408bfdbc0a5a87d373104cbdc2e9bd..c603e75ad35438deb4311be5bdc68b64022da776 100644
--- a/src/utils/dpad.js
+++ b/src/utils/dpad.js
@@ -13,7 +13,7 @@ export function angleTo4Direction(angle) {
 
 export function angleTo8Direction(angle) {
   angle = (angle * THREE.Math.RAD2DEG + 180 + 45) % 360;
-  var direction = "";
+  let direction = "";
   if ((angle >= 0 && angle < 120) || angle >= 330) {
     direction += "north";
   }
diff --git a/webpack.config.js b/webpack.config.js
index d404babbb6d5af438271621b4e3f2fbac235a266..495cd0ab57448bb2e24470f36969c2261465f1bd 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -14,8 +14,6 @@ function createHTTPSConfig() {
     return false;
   }
 
-  let https;
-
   // Generate certs for the local webpack-dev-server.
   if (fs.existsSync(path.join(__dirname, "certs"))) {
     const key = fs.readFileSync(path.join(__dirname, "certs", "key.pem"));
@@ -77,7 +75,7 @@ const config = {
   entry: {
     lobby: path.join(__dirname, "src", "lobby.js"),
     room: path.join(__dirname, "src", "room.js"),
-    'avatar-selector': path.join(__dirname, "src", "avatar-selector.js"),
+    "avatar-selector": path.join(__dirname, "src", "avatar-selector.js"),
     onboarding: path.join(__dirname, "src", "onboarding.js")
   },
   output: {
@@ -97,7 +95,7 @@ const config = {
       // networked-aframe makes HEAD requests to the server for time syncing. Respond with an empty body.
       app.head("*", function(req, res, next) {
         if (req.method === "HEAD") {
-          res.append("Date", (new Date()).toGMTString());
+          res.append("Date", new Date().toGMTString());
           res.send("");
         } else {
           next();