diff --git a/src/components/ambient-light.js b/src/components/ambient-light.js
new file mode 100644
index 0000000000000000000000000000000000000000..274ba770a7a48e67a7a4a77e5b37fcabb35763e3
--- /dev/null
+++ b/src/components/ambient-light.js
@@ -0,0 +1,27 @@
+AFRAME.registerComponent("ambient-light", {
+  schema: {
+    color: { type: "color" },
+    intensity: { default: 1.0 }
+  },
+
+  init() {
+    const el = this.el;
+    this.light = new THREE.AmbientLight();
+    this.el.setObject3D("ambient-light", this.light);
+    this.el.sceneEl.systems.light.registerLight(el);
+  },
+
+  update(prevData) {
+    if (this.data.color !== prevData.color) {
+      this.light.color.set(this.data.color);
+    }
+
+    if (this.data.intensity !== prevData.intensity) {
+      this.light.intensity = this.data.intensity;
+    }
+  },
+
+  remove: function() {
+    this.el.removeObject3D("ambient-light");
+  }
+});
diff --git a/src/components/directional-light.js b/src/components/directional-light.js
new file mode 100644
index 0000000000000000000000000000000000000000..7db6bc2cde1fc611a8e9ed92b89736d47c04b6f0
--- /dev/null
+++ b/src/components/directional-light.js
@@ -0,0 +1,33 @@
+AFRAME.registerComponent("directional-light", {
+  schema: {
+    color: { type: "color" },
+    intensity: { default: 1.0 },
+    castShadow: { default: true }
+  },
+
+  init() {
+    const el = this.el;
+    this.light = new THREE.DirectionalLight();
+    this.light.target.position.set(0, 0, 1);
+    this.el.setObject3D("directional-light", this.light);
+    this.el.sceneEl.systems.light.registerLight(el);
+  },
+
+  update(prevData) {
+    if (this.data.color !== prevData.color) {
+      this.light.color.set(this.data.color);
+    }
+
+    if (this.data.intensity !== prevData.intensity) {
+      this.light.intensity = this.data.intensity;
+    }
+
+    if (this.data.castShadow !== prevData.castShadow) {
+      this.light.castShadow = this.data.castShadow;
+    }
+  },
+
+  remove: function() {
+    this.el.removeObject3D("directional-light");
+  }
+});
diff --git a/src/components/hemisphere-light.js b/src/components/hemisphere-light.js
new file mode 100644
index 0000000000000000000000000000000000000000..43e2d730af5830b2b632312d0a96656fcd4ccdc0
--- /dev/null
+++ b/src/components/hemisphere-light.js
@@ -0,0 +1,32 @@
+AFRAME.registerComponent("hemisphere-light", {
+  schema: {
+    skyColor: { type: "color" },
+    groundColor: { type: "color" },
+    intensity: { default: 1.0 }
+  },
+
+  init() {
+    const el = this.el;
+    this.light = new THREE.HemisphereLight();
+    this.el.setObject3D("hemisphere-light", this.light);
+    this.el.sceneEl.systems.light.registerLight(el);
+  },
+
+  update(prevData) {
+    if (this.data.skyColor !== prevData.skyColor) {
+      this.light.skyColor.set(this.data.skyColor);
+    }
+
+    if (this.data.groundColor !== prevData.groundColor) {
+      this.light.groundColor.set(this.data.groundColor);
+    }
+
+    if (this.data.intensity !== prevData.intensity) {
+      this.light.intensity = this.data.intensity;
+    }
+  },
+
+  remove: function() {
+    this.el.removeObject3D("hemisphere-light");
+  }
+});
diff --git a/src/components/point-light.js b/src/components/point-light.js
new file mode 100644
index 0000000000000000000000000000000000000000..2d75eb84b2bdf6a868dea2bb664657c74919e792
--- /dev/null
+++ b/src/components/point-light.js
@@ -0,0 +1,38 @@
+AFRAME.registerComponent("point-light", {
+  schema: {
+    color: { type: "color" },
+    intensity: { default: 1.0 },
+    range: { default: 0 },
+    castShadow: { default: true }
+  },
+
+  init() {
+    const el = this.el;
+    this.light = new THREE.PointLight();
+    this.light.decay = 2;
+    this.el.setObject3D("point-light", this.light);
+    this.el.sceneEl.systems.light.registerLight(el);
+  },
+
+  update(prevData) {
+    if (this.data.color !== prevData.color) {
+      this.light.color.set(this.data.color);
+    }
+
+    if (this.data.intensity !== prevData.intensity) {
+      this.light.intensity = this.data.intensity;
+    }
+
+    if (this.data.range !== prevData.range) {
+      this.light.distance = this.data.range;
+    }
+
+    if (this.data.castShadow !== prevData.castShadow) {
+      this.light.castShadow = this.data.castShadow;
+    }
+  },
+
+  remove: function() {
+    this.el.removeObject3D("point-light");
+  }
+});
diff --git a/src/components/spot-light.js b/src/components/spot-light.js
new file mode 100644
index 0000000000000000000000000000000000000000..930ff89b5e970381286f4d4932928479ebc50e14
--- /dev/null
+++ b/src/components/spot-light.js
@@ -0,0 +1,46 @@
+AFRAME.registerComponent("spot-light", {
+  schema: {
+    color: { type: "color" },
+    intensity: { default: 1.0 },
+    range: { default: 0 },
+    innerConeAngle: { default: 0 },
+    outerConeAngle: { default: Math.PI / 4.0 },
+    castShadow: { default: true }
+  },
+
+  init() {
+    const el = this.el;
+    this.light = new THREE.SpotLight();
+    this.light.target.position.set(0, 0, 1);
+    this.light.decay = 2;
+    this.el.setObject3D("spot-light", this.light);
+    this.el.sceneEl.systems.light.registerLight(el);
+  },
+
+  update(prevData) {
+    if (this.data.color !== prevData.color) {
+      this.light.color.set(this.data.color);
+    }
+
+    if (this.data.intensity !== prevData.intensity) {
+      this.light.intensity = this.data.intensity;
+    }
+
+    if (this.data.range !== prevData.range) {
+      this.light.distance = this.data.range;
+    }
+
+    if (this.data.innerConeAngle !== prevData.innerConeAngle || this.data.outerConeAngle !== prevData.outerConeAngle) {
+      this.light.angle = this.data.outerConeAngle;
+      this.light.penumbra = 1.0 - this.data.innerConeAngle / this.data.outerConeAngle;
+    }
+
+    if (this.data.castShadow !== prevData.castShadow) {
+      this.light.castShadow = this.data.castShadow;
+    }
+  },
+
+  remove: function() {
+    this.el.removeObject3D("spot-light");
+  }
+});
diff --git a/src/gltf-component-mappings.js b/src/gltf-component-mappings.js
index 835107d15deed8178150f914ec3bd4e076aaba2e..aa4f9f0ed67a5dea2bf01c5c8c5883b8010e59d4 100644
--- a/src/gltf-component-mappings.js
+++ b/src/gltf-component-mappings.js
@@ -11,9 +11,11 @@ AFRAME.GLTFModelPlus.registerComponent("gltf-model-plus", "gltf-model-plus");
 AFRAME.GLTFModelPlus.registerComponent("body", "body");
 AFRAME.GLTFModelPlus.registerComponent("hide-when-quality", "hide-when-quality");
 AFRAME.GLTFModelPlus.registerComponent("light", "light");
-AFRAME.GLTFModelPlus.registerComponent("directional-light", "light");
-AFRAME.GLTFModelPlus.registerComponent("ambient-light", "light");
-AFRAME.GLTFModelPlus.registerComponent("point-light", "light");
+AFRAME.GLTFModelPlus.registerComponent("ambient-light", "ambient-light");
+AFRAME.GLTFModelPlus.registerComponent("directional-light", "directional-light");
+AFRAME.GLTFModelPlus.registerComponent("hemisphere-light", "hemisphere-light");
+AFRAME.GLTFModelPlus.registerComponent("point-light", "point-light");
+AFRAME.GLTFModelPlus.registerComponent("spot-light", "spot-light");
 AFRAME.GLTFModelPlus.registerComponent("skybox", "skybox");
 AFRAME.GLTFModelPlus.registerComponent("layers", "layers");
 AFRAME.GLTFModelPlus.registerComponent("shadow", "shadow");
diff --git a/src/hub.js b/src/hub.js
index 6af7d7750f56f9d37718ab90b0378ef6808fdf08..ff3d783f2f003e3682bdf891f3ea5d230be1f4ee 100644
--- a/src/hub.js
+++ b/src/hub.js
@@ -75,6 +75,11 @@ import "./components/remove-networked-object-button";
 import "./components/destroy-at-extreme-distances";
 import "./components/media-loader";
 import "./components/gamma-factor";
+import "./components/ambient-light";
+import "./components/directional-light";
+import "./components/hemisphere-light";
+import "./components/point-light";
+import "./components/spot-light";
 
 import ReactDOM from "react-dom";
 import React from "react";