diff --git a/demos/combustion_demo/src/combustion_demo.cpp b/demos/combustion_demo/src/combustion_demo.cpp
index 12764cf1d6e2dcf5ed6d1069ddbd4e6bf9d030b4..6dcf3386a188dcedeb358faca71d05b53f389b69 100644
--- a/demos/combustion_demo/src/combustion_demo.cpp
+++ b/demos/combustion_demo/src/combustion_demo.cpp
@@ -33,11 +33,12 @@
 #include "phx/input/device_system.hpp"
 #include "phx/input/input_system.hpp"
 #include "phx/rendering/auxiliary/splash_screen.hpp"
-#include "phx/rendering/components/mesh_handle.hpp"
 #include "phx/rendering/components/mesh_render_settings.hpp"
+#include "phx/rendering/components/resource_component.hpp"
 #include "phx/rendering/components/skybox.hpp"
 #include "phx/resources/loaders/assimp_model_loader.hpp"
 #include "phx/resources/loaders/scene_loader.hpp"
+#include "phx/resources/resource_manager.hpp"
 #include "phx/setup.hpp"
 #include "vr_controller_interaction_behavior.hpp"
 
@@ -92,8 +93,8 @@ int main(int, char**) {
     auto surface_material_handle =
         surface_transform->GetChild(0)
             ->GetEntity()
-            ->GetFirstComponent<phx::MaterialHandle>();
-    auto surface_material = surface_material_handle->GetMaterial();
+            ->GetFirstComponent<phx::ResourceComponent<phx::Material>>();
+    auto surface_material = surface_material_handle->GetResourcePointer();
     surface_material->SetAmbientColor(glm::vec3(0.1f));
     surface_material->SetDiffuseColor(glm::vec3(1.0f));
     surface_material->SetSpecularColor(glm::vec3(0.4f));
@@ -106,13 +107,14 @@ int main(int, char**) {
     auto boundigbox_mesh_entity =
         boundingbox_transform->GetChild(0)->GetEntity();
     auto boundingbox_mesh_handle =
-        boundigbox_mesh_entity->GetFirstComponent<phx::MeshHandle>();
+        boundigbox_mesh_entity
+            ->GetFirstComponent<phx::ResourceComponent<phx::Mesh>>();
     auto render_settings =
         boundigbox_mesh_entity->AddComponent<phx::MeshRenderSettings>();
     render_settings->SetWireframeMode(true);
 
     std::array<glm::vec3, 2> bbox =
-        boundingbox_mesh_handle->GetMesh()->GetBoundingBox();
+        boundingbox_mesh_handle->GetResourcePointer()->GetBoundingBox();
     glm::vec3 bbox_diff = bbox[1] - bbox[0];
     glm::vec3 center_vec = bbox_diff * 0.5f * 0.001f;
     surface_transform->SetLocalTranslation(-center_vec);
@@ -130,13 +132,14 @@ int main(int, char**) {
         "models/cube/cube.obj", scene.get());
     auto floor_transform = floor_entity->GetFirstComponent<phx::Transform>();
     floor_transform->SetLocalScale(glm::vec3(1000.0f, 0.05f, 1000.0f));
-    auto floor_material = floor_transform->GetChild(0)
-                              ->GetEntity()
-                              ->GetFirstComponent<phx::MaterialHandle>();
-    floor_material->GetMaterial()->SetDiffuseColor(glm::vec3(0.5f, 0.5f, 0.5f));
-    floor_material->GetMaterial()->SetSpecularColor(
-        glm::vec3(1.0f, 1.0f, 1.0f));
-    floor_material->GetMaterial()->SetAmbientColor(glm::vec3(0.1f, 0.1f, 0.1f));
+    auto floor_material =
+        floor_transform->GetChild(0)
+            ->GetEntity()
+            ->GetFirstComponent<phx::ResourceComponent<phx::Material>>()
+            ->GetResourcePointer();
+    floor_material->SetDiffuseColor(glm::vec3(0.5f, 0.5f, 0.5f));
+    floor_material->SetSpecularColor(glm::vec3(1.0f, 1.0f, 1.0f));
+    floor_material->SetAmbientColor(glm::vec3(0.1f, 0.1f, 0.1f));
 
     if (right_interaction_behavior)
       right_interaction_behavior->SetTarget(vis_root_transform);
@@ -145,12 +148,14 @@ int main(int, char**) {
         "models/cube/cube2.obj", scene.get());
     auto desk_transform = desk_entity->GetFirstComponent<phx::Transform>();
     desk_transform->SetLocalScale(glm::vec3(2.0f, 0.03f, 1.0f));
-    auto desk_material = desk_transform->GetChild(0)
-                             ->GetEntity()
-                             ->GetFirstComponent<phx::MaterialHandle>();
-    desk_material->GetMaterial()->SetDiffuseColor(glm::vec3(0.5f, 1.0f, 0.5f));
-    desk_material->GetMaterial()->SetSpecularColor(glm::vec3(1.0f, 1.0f, 1.0f));
-    desk_material->GetMaterial()->SetAmbientColor(glm::vec3(0.1f, 0.2f, 0.1f));
+    auto desk_material =
+        desk_transform->GetChild(0)
+            ->GetEntity()
+            ->GetFirstComponent<phx::ResourceComponent<phx::Material>>()
+            ->GetResourcePointer();
+    desk_material->SetDiffuseColor(glm::vec3(0.5f, 1.0f, 0.5f));
+    desk_material->SetSpecularColor(glm::vec3(1.0f, 1.0f, 1.0f));
+    desk_material->SetAmbientColor(glm::vec3(0.1f, 0.2f, 0.1f));
 
     auto desk_root = scene->CreateEntity();
     auto desk_root_transform = desk_root->AddComponent<phx::Transform>();
diff --git a/demos/viewer/src/viewer.cpp b/demos/viewer/src/viewer.cpp
index a43834aba9cadeb24c0425e9c2373a7b4026f78d..17a69139c70cb2d80c4dde43be2d62e00d319dd6 100644
--- a/demos/viewer/src/viewer.cpp
+++ b/demos/viewer/src/viewer.cpp
@@ -38,7 +38,6 @@
 #include "phx/rendering/auxiliary/splash_screen.hpp"
 #include "phx/rendering/components/light.hpp"
 #include "phx/rendering/components/transform.hpp"
-#include "phx/rendering/rendering_system.hpp"
 #include "phx/resources/loaders/assimp_model_loader.hpp"
 #include "phx/resources/loaders/scene_loader.hpp"
 #include "phx/resources/resource_manager.hpp"
diff --git a/library/phx/core/component.hpp b/library/phx/core/component.hpp
index 1faa0952bfa7cc2cfdd9ad077f0a654758cc77a4..e80fdc571ef93fb294bd122e5ca414d4a37d79dc 100644
--- a/library/phx/core/component.hpp
+++ b/library/phx/core/component.hpp
@@ -26,8 +26,8 @@
 #include <ostream>
 #include <string>
 
-#include "phx/utility/aspects/loggable.hpp"
 #include "phx/export.hpp"
+#include "phx/utility/aspects/loggable.hpp"
 
 namespace phx {
 
diff --git a/library/phx/core/entity.hpp b/library/phx/core/entity.hpp
index 993438548637bb1baa3fb112dad705b52456e217..adfac064637694a8a3c8a65d30b9ace7ced65a5c 100644
--- a/library/phx/core/entity.hpp
+++ b/library/phx/core/entity.hpp
@@ -31,9 +31,9 @@
 #include <vector>
 
 #include "phx/core/component.hpp"
+#include "phx/export.hpp"
 #include "phx/utility/aspects/loggable.hpp"
 #include "phx/utility/aspects/nameable.hpp"
-#include "phx/export.hpp"
 
 namespace phx {
 
diff --git a/library/phx/input/openvr_controller_model_system.cpp b/library/phx/input/openvr_controller_model_system.cpp
index 643328fc5d8d7169f2b312a6ea9573d3dda354b2..b1cffb951508ae025ec6b8962a1ddafdb8b05c94 100644
--- a/library/phx/input/openvr_controller_model_system.cpp
+++ b/library/phx/input/openvr_controller_model_system.cpp
@@ -30,8 +30,7 @@
 #include "phx/display/display_system_openvr.hpp"
 #include "phx/input/openvr_controller_behavior.hpp"
 #include "phx/input/vr_controller.hpp"
-#include "phx/rendering/components/material_handle.hpp"
-#include "phx/rendering/components/mesh_handle.hpp"
+#include "phx/rendering/components/resource_component.hpp"
 #include "phx/rendering/components/transform.hpp"
 #include "phx/resources/loaders/openvr_resource_loader.hpp"
 #include "phx/resources/resource_manager.hpp"
@@ -80,9 +79,9 @@ Entity* OpenVRControllerModelSystem::AddControllerEntity(
     phx::Scene* scene, ResourcePointer<Mesh> mesh,
     ResourcePointer<Material> material, VRController::ControllerSide side) {
   Entity* controller = scene->CreateEntity();
-  controller->AddComponent<MeshHandle>()->SetMesh(mesh);
+  controller->AddComponent<ResourceComponent<Mesh>>(mesh);
   controller->AddComponent<Transform>();
-  controller->AddComponent<MaterialHandle>()->SetMaterial(material);
+  controller->AddComponent<ResourceComponent<Material>>(material);
   controller->AddComponent<OpenVRControllerBehavior>()->SetSide(side);
 
   return controller;
diff --git a/library/phx/rendering/components/material_handle.cpp b/library/phx/rendering/components/material_handle.cpp
deleted file mode 100644
index 0e058bba73ae1c5d0bab1fac7f947951bb5a77fa..0000000000000000000000000000000000000000
--- a/library/phx/rendering/components/material_handle.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//------------------------------------------------------------------------------
-// Project Phoenix
-//
-// Copyright (c) 2017-2018 RWTH Aachen University, Germany,
-// Virtual Reality & Immersive Visualization Group.
-//------------------------------------------------------------------------------
-//                                 License
-//
-// Licensed under the 3-Clause BSD License (the "License");
-// you may not use this file except in compliance with the License.
-// See the file LICENSE for the full text.
-// You may obtain a copy of the License at
-//
-//     https://opensource.org/licenses/BSD-3-Clause
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//------------------------------------------------------------------------------
-
-#include "phx/rendering/components/material_handle.hpp"
-
-#include <iostream>
-#include <string>
-
-#include "phx/core/logger.hpp"
-
-namespace phx {
-
-void MaterialHandle::SetMaterial(ResourcePointer<Material> material) {
-  material_ = material;
-}
-
-ResourcePointer<Material> MaterialHandle::GetMaterial() const {
-  return material_;
-}
-
-std::string MaterialHandle::ToString() const {
-  return GetName() + " (MaterialComponent)";
-}
-}  // namespace phx
diff --git a/library/phx/rendering/components/mesh_handle.cpp b/library/phx/rendering/components/mesh_handle.cpp
deleted file mode 100644
index 85fd32a7fcc2feea41f9f8f115e816a67c71fff3..0000000000000000000000000000000000000000
--- a/library/phx/rendering/components/mesh_handle.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//------------------------------------------------------------------------------
-// Project Phoenix
-//
-// Copyright (c) 2017-2018 RWTH Aachen University, Germany,
-// Virtual Reality & Immersive Visualization Group.
-//------------------------------------------------------------------------------
-//                                 License
-//
-// Licensed under the 3-Clause BSD License (the "License");
-// you may not use this file except in compliance with the License.
-// See the file LICENSE for the full text.
-// You may obtain a copy of the License at
-//
-//     https://opensource.org/licenses/BSD-3-Clause
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//------------------------------------------------------------------------------
-
-#include "phx/rendering/components/mesh_handle.hpp"
-
-#include <string>
-
-#include "phx/resources/types/mesh.hpp"
-
-namespace phx {
-
-void MeshHandle::SetMesh(ResourcePointer<Mesh> mesh) { mesh_ = mesh; }
-
-ResourcePointer<Mesh> MeshHandle::GetMesh() const { return mesh_; }
-
-std::string MeshHandle::ToString() const {
-  if (mesh_ == nullptr) return GetName() + " (MeshHandle <empty>)";
-
-  auto mesh = this->GetMesh();
-  return GetName() + " (MeshHandle" +
-         " #Vertices: " + std::to_string(mesh->GetVertices().size()) +
-         " #Normals: " + std::to_string(mesh->GetNormals().size()) +
-         " #TexCoords: " + std::to_string(mesh->GetTextureCoords().size()) +
-         " #Tangents: " + std::to_string(mesh->GetTangents().size()) +
-         " #Bitangents: " + std::to_string(mesh->GetBitangents().size()) +
-         " #Indices: " + std::to_string(mesh->GetIndices().size()) + ")";
-}
-
-}  // namespace phx
diff --git a/library/phx/rendering/components/mesh_handle.hpp b/library/phx/rendering/components/mesh_handle.hpp
deleted file mode 100644
index 9ad2de1e10c9dbfd2f82b9636795000f366c2181..0000000000000000000000000000000000000000
--- a/library/phx/rendering/components/mesh_handle.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-//------------------------------------------------------------------------------
-// Project Phoenix
-//
-// Copyright (c) 2017-2018 RWTH Aachen University, Germany,
-// Virtual Reality & Immersive Visualization Group.
-//------------------------------------------------------------------------------
-//                                 License
-//
-// Licensed under the 3-Clause BSD License (the "License");
-// you may not use this file except in compliance with the License.
-// See the file LICENSE for the full text.
-// You may obtain a copy of the License at
-//
-//     https://opensource.org/licenses/BSD-3-Clause
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//------------------------------------------------------------------------------
-#ifndef LIBRARY_PHX_RENDERING_COMPONENTS_MESH_HANDLE_HPP_
-#define LIBRARY_PHX_RENDERING_COMPONENTS_MESH_HANDLE_HPP_
-
-#include <string>
-
-#include "phx/core/component.hpp"
-#include "phx/export.hpp"
-#include "phx/resources/resource_pointer.hpp"
-#include "phx/resources/types/mesh.hpp"
-#include "phx/utility/aspects/nameable.hpp"
-
-namespace phx {
-/**
- * A component holding a simple pointer to a mesh
- */
-class PHOENIX_EXPORT MeshHandle final : public Component, public Nameable {
- public:
-  ~MeshHandle() override = default;
-
-  void SetMesh(ResourcePointer<Mesh> mesh);
-  ResourcePointer<Mesh> GetMesh() const;
-
-  std::string ToString() const override;
-
- protected:
-  friend Entity;
-  MeshHandle() = default;
-  MeshHandle(const MeshHandle&) = delete;
-  MeshHandle(MeshHandle&&) = default;
-
-  MeshHandle& operator=(const MeshHandle&) = delete;
-  MeshHandle& operator=(MeshHandle&&) = default;
-
- private:
-  ResourcePointer<Mesh> mesh_{nullptr};
-};
-}  // namespace phx
-
-#endif  // LIBRARY_PHX_RENDERING_COMPONENTS_MESH_HANDLE_HPP_
diff --git a/library/phx/rendering/components/material_handle.hpp b/library/phx/rendering/components/resource_component.hpp
similarity index 55%
rename from library/phx/rendering/components/material_handle.hpp
rename to library/phx/rendering/components/resource_component.hpp
index a2a5a14442cccc3b29a88c10fa6f811199754af1..30671dc1579be7fb52f06d7d834adabb52c2ef91 100644
--- a/library/phx/rendering/components/material_handle.hpp
+++ b/library/phx/rendering/components/resource_component.hpp
@@ -20,46 +20,45 @@
 // limitations under the License.
 //------------------------------------------------------------------------------
 
-#ifndef LIBRARY_PHX_RENDERING_COMPONENTS_MATERIAL_HANDLE_HPP_
-#define LIBRARY_PHX_RENDERING_COMPONENTS_MATERIAL_HANDLE_HPP_
+#ifndef LIBRARY_PHX_RENDERING_COMPONENTS_RESOURCE_COMPONENT_HPP_
+#define LIBRARY_PHX_RENDERING_COMPONENTS_RESOURCE_COMPONENT_HPP_
 
 #include <string>
-#include <vector>
-
-#include "phx/suppress_warnings.hpp"
-
-SUPPRESS_WARNINGS_BEGIN
-#include "glm/vec3.hpp"
-SUPPRESS_WARNINGS_END
 
 #include "phx/core/component.hpp"
-#include "phx/resources/types/material.hpp"
-#include "phx/resources/resource_pointer.hpp"
-#include "phx/utility/aspects/nameable.hpp"
 #include "phx/export.hpp"
+#include "phx/resources/resource_pointer.hpp"
 
 namespace phx {
 
-class PHOENIX_EXPORT MaterialHandle final : public Component, public Nameable {
+template <class ResourceType>
+class PHOENIX_EXPORT ResourceComponent final : public Component {
  public:
-  void SetMaterial(ResourcePointer<Material> material);
-  ResourcePointer<Material> GetMaterial() const;
+  std::string ToString() const override { return "Resource Pointer Component"; }
+
+  ResourcePointer<ResourceType> GetResourcePointer() {
+    return resource_pointer_;
+  }
 
-  std::string ToString() const override;
+  void SetResourcePointer(ResourcePointer<ResourceType> pointer) {
+    resource_pointer_ = pointer;
+  }
 
  protected:
   friend Entity;
-  MaterialHandle() = default;
-  MaterialHandle(const MaterialHandle&) = delete;
-  MaterialHandle(MaterialHandle&&) = default;
+  ResourceComponent() = default;
+  explicit ResourceComponent(ResourcePointer<ResourceType> pointer)
+      : resource_pointer_(pointer) {}
+  ResourceComponent(const ResourceComponent&) = delete;
+  ResourceComponent(ResourceComponent&&) = default;
 
-  MaterialHandle& operator=(const MaterialHandle&) = delete;
-  MaterialHandle& operator=(MaterialHandle&&) = default;
+  ResourceComponent& operator=(const ResourceComponent&) = delete;
+  ResourceComponent& operator=(ResourceComponent&&) = default;
 
  private:
-  ResourcePointer<Material> material_{nullptr};
+  ResourcePointer<ResourceType> resource_pointer_;
 };
 
 }  // namespace phx
 
-#endif  // LIBRARY_PHX_RENDERING_COMPONENTS_MATERIAL_HANDLE_HPP_
+#endif  // LIBRARY_PHX_RENDERING_COMPONENTS_RESOURCE_COMPONENT_HPP_
diff --git a/library/phx/rendering/render_passes/geometry_pass.hpp b/library/phx/rendering/render_passes/geometry_pass.hpp
index a02733159fc998a2b8547c5565932bbf118e1203..28450ed30182157428211bbdb10e2592bb60f7a0 100644
--- a/library/phx/rendering/render_passes/geometry_pass.hpp
+++ b/library/phx/rendering/render_passes/geometry_pass.hpp
@@ -40,12 +40,11 @@ SUPPRESS_WARNINGS_END
 #include "phx/rendering/backend/render_target.hpp"
 #include "phx/rendering/backend/shader_program.hpp"
 #include "phx/rendering/components/light.hpp"
-#include "phx/rendering/components/material_handle.hpp"
 #include "phx/rendering/components/mesh_render_settings.hpp"
 #include "phx/rendering/components/projection.hpp"
 #include "phx/rendering/components/transform.hpp"
 #include "phx/rendering/render_passes/render_pass.hpp"
-#include "phx/resources/resource_manager.hpp"
+#include "phx/resources/types/material.hpp"
 #include "phx/resources/types/mesh.hpp"
 
 namespace phx {
diff --git a/library/phx/rendering/rendering_system.cpp b/library/phx/rendering/rendering_system.cpp
index 7e9a59d963c9c06add6b051736bb304d0a52bddf..a642caa62e7739f05f5ae5a228e964d0d005fa7d 100644
--- a/library/phx/rendering/rendering_system.cpp
+++ b/library/phx/rendering/rendering_system.cpp
@@ -32,12 +32,14 @@
 #include "phx/core/scene.hpp"
 #include "phx/core/system.hpp"
 #include "phx/rendering/components/light.hpp"
-#include "phx/rendering/components/material_handle.hpp"
-#include "phx/rendering/components/mesh_handle.hpp"
 #include "phx/rendering/components/mesh_render_settings.hpp"
+#include "phx/rendering/components/resource_component.hpp"
 #include "phx/rendering/components/skybox.hpp"
 #include "phx/rendering/components/transform.hpp"
 #include "phx/rendering/render_passes/skybox_pass.hpp"
+#include "phx/resources/resource_pointer.hpp"
+#include "phx/resources/types/material.hpp"
+#include "phx/resources/types/mesh.hpp"
 
 #include "gl/debug.hpp"
 #include "gl/opengl.hpp"
@@ -78,19 +80,22 @@ void RenderingSystem::Update(const FrameTimer::TimeInfo&) {
   Skybox* skybox = nullptr;
 
   for (auto& entity : GetEngine()->GetEntities()) {
-    auto mesh_handle = entity->GetFirstComponent<MeshHandle>();
     auto light = entity->GetFirstComponent<Light>();
     auto transform = entity->GetFirstComponent<Transform>();
-    auto material_handle = entity->GetFirstComponent<MaterialHandle>();
-    Material* material = nullptr;
-    if (material_handle != nullptr)
-      material = material_handle->GetMaterial().Get();
-    auto mesh_render_settings = entity->GetFirstComponent<MeshRenderSettings>();
 
+    const auto material =
+        entity->GetFirstComponent<ResourceComponent<Material>>();
+    const auto mesh = entity->GetFirstComponent<ResourceComponent<Mesh>>();
+    const auto mesh_render_settings =
+        entity->GetFirstComponent<MeshRenderSettings>();
     if (transform != nullptr) {
-      if (mesh_handle != nullptr) {
-        rendering_instances.push_back({mesh_handle->GetMesh().Get(), material,
-                                       transform, mesh_render_settings});
+      if (mesh != nullptr) {
+        rendering_instances.push_back(
+            {mesh->GetResourcePointer().Get(),
+             (material != nullptr ? material->GetResourcePointer().Get()
+                                  : nullptr),
+             transform, mesh_render_settings});
+
       } else if (light != nullptr) {
         light_transform_pairs.push_back(
             std::pair<Light*, Transform*>(light, transform));
diff --git a/library/phx/resources/loaders/scene_loader.cpp b/library/phx/resources/loaders/scene_loader.cpp
index e77a9a515972dd20efe24488d0cf22fff3f54500..776e321e00429ed263ca6fc1e7bbc274bcb5de96 100644
--- a/library/phx/resources/loaders/scene_loader.cpp
+++ b/library/phx/resources/loaders/scene_loader.cpp
@@ -24,12 +24,13 @@
 
 #include <string>
 
-#include "phx/rendering/components/material_handle.hpp"
-#include "phx/rendering/components/mesh_handle.hpp"
+#include "phx/rendering/components/resource_component.hpp"
 #include "phx/rendering/components/transform.hpp"
-#include "phx/resources/types/model.hpp"
-#include "phx/resources/resource_manager.hpp"
+#include "phx/resources/resource_pointer.hpp"
 #include "phx/resources/resource_utils.hpp"
+#include "phx/resources/types/material.hpp"
+#include "phx/resources/types/mesh.hpp"
+#include "phx/resources/types/model.hpp"
 
 namespace phx {
 
@@ -47,10 +48,10 @@ phx::Entity* SceneLoader::InsertModelIntoScene(const std::string& file_name,
   for (auto mesh : model->GetMeshes()) {
     auto entity = scene->CreateEntity();
     entity->AddComponent<Transform>()->SetParent(root_transform);
-    entity->AddComponent<MeshHandle>()->SetMesh(mesh);
+    entity->AddComponent<ResourceComponent<Mesh>>(mesh);
     ResourcePointer<Material> material = model->GetMaterialForMesh(mesh);
     if (material != nullptr) {
-      entity->AddComponent<MaterialHandle>()->SetMaterial(material);
+      entity->AddComponent<ResourceComponent<Material>>(material);
     }
   }
 
diff --git a/library/phx/resources/resource_pointer.hpp b/library/phx/resources/resource_pointer.hpp
index 3ee0ca1f5298cf4018f7d65269f913734e194856..123f9a569612142f22d55caa82b2260a5c0a4f34 100644
--- a/library/phx/resources/resource_pointer.hpp
+++ b/library/phx/resources/resource_pointer.hpp
@@ -25,8 +25,8 @@
 
 #include <cstddef>
 
-#include "phx/resources/resource_proxy.hpp"
 #include "phx/export.hpp"
+#include "phx/resources/resource_proxy.hpp"
 
 namespace phx {
 
@@ -62,8 +62,12 @@ class PHOENIX_EXPORT ResourcePointer {
 
   ResourceType *Get() const { return proxy_->GetAs<ResourceType>(); }
 
-  void Load() { if (proxy_) proxy_->Load(); }
-  void Unload() { if (proxy_) proxy_->Unload(); }
+  void Load() {
+    if (proxy_) proxy_->Load();
+  }
+  void Unload() {
+    if (proxy_) proxy_->Unload();
+  }
 
  private:
   ResourceProxy *proxy_;
diff --git a/tests/src/integration_test_model_rendering.cpp b/tests/src/integration_test_model_rendering.cpp
index 39761c2ea606701292d9b3c2a9653c5fdc14f45b..bd1fe2a93583f17ca2581016e7d0f9a6406d5154 100644
--- a/tests/src/integration_test_model_rendering.cpp
+++ b/tests/src/integration_test_model_rendering.cpp
@@ -32,11 +32,10 @@
 #include "phx/display/display_system_window.hpp"
 #include "phx/display/window.hpp"
 #include "phx/rendering/backend/opengl_image_buffer_data.hpp"
-#include "phx/rendering/components/mesh_handle.hpp"
 #include "phx/rendering/components/mesh_render_settings.hpp"
+#include "phx/rendering/components/resource_component.hpp"
 #include "phx/rendering/rendering_system.hpp"
 #include "phx/resources/loaders/assimp_model_loader.hpp"
-#include "phx/resources/resource_manager.hpp"
 #include "phx/resources/resource_utils.hpp"
 #include "phx/resources/types/mesh.hpp"
 #include "phx/setup.hpp"
@@ -55,20 +54,15 @@ SUPPRESS_WARNINGS_BEGIN_MISSING_DECLARATIONS
 
 phx::Entity* LoadBunny(glm::vec3 pos, float angleDeg,
                        const std::string& material_name, phx::Scene* scene) {
-  auto bunny_mesh = phx::ResourceUtils::LoadResourceFromFile<phx::Mesh>(
-      "models/bunny.obj", {{"mesh_index", 0}});
-
   phx::Entity* bunny = scene->CreateEntity();
 
-  phx::MeshHandle* bunny_handle = bunny->AddComponent<phx::MeshHandle>();
-  bunny_handle->SetMesh(bunny_mesh);
-
-  phx::MaterialHandle* bunny_material_handle =
-      bunny->AddComponent<phx::MaterialHandle>();
+  auto bunny_mesh = phx::ResourceUtils::LoadResourceFromFile<phx::Mesh>(
+      "models/bunny.obj", {{"mesh_index", 0}});
+  bunny->AddComponent<phx::ResourceComponent<phx::Mesh>>(bunny_mesh);
 
   auto bunny_material = phx::ResourceUtils::LoadResourceFromFile<phx::Material>(
       "models/bunny.obj", {{"material_name", material_name}});
-  bunny_material_handle->SetMaterial(bunny_material);
+  bunny->AddComponent<phx::ResourceComponent<phx::Material>>(bunny_material);
 
   phx::Transform* bunny_transform = bunny->AddComponent<phx::Transform>();
   bunny_transform->SetLocalTranslation(pos);
diff --git a/tests/src/integration_test_opengl_buffer_data_download.cpp b/tests/src/integration_test_opengl_buffer_data_download.cpp
index 237f49bd5455d3867d9fa9feb85596c1429f7193..70137dd96183d8cd62ff91388f54ecf3137f0668 100644
--- a/tests/src/integration_test_opengl_buffer_data_download.cpp
+++ b/tests/src/integration_test_opengl_buffer_data_download.cpp
@@ -34,9 +34,8 @@
 #include "phx/core/scene.hpp"
 #include "phx/display/window.hpp"
 #include "phx/rendering/backend/opengl_image_buffer_data.hpp"
-#include "phx/rendering/components/mesh_handle.hpp"
+#include "phx/rendering/components/resource_component.hpp"
 #include "phx/rendering/rendering_system.hpp"
-#include "phx/resources/resource_declaration.hpp"
 #include "phx/resources/resource_manager.hpp"
 #include "phx/resources/resource_pointer.hpp"
 #include "phx/resources/types/mesh.hpp"
@@ -94,9 +93,7 @@ class SceneSetupSimple {
         "custommaterial", glm::vec3(), glm::vec3(), glm::vec3(1.f, 0.5f, 0.25f),
         500.f);
 
-    phx::MaterialHandle* material_handle =
-        triangle->AddComponent<phx::MaterialHandle>();
-    material_handle->SetMaterial(material);
+    triangle->AddComponent<phx::ResourceComponent<phx::Material>>(material);
 
     std::vector<glm::vec3> vertices = {
         {-4.0f, -3.0f, -0.05f}, {4.0f, -3.0f, -0.05f}, {4.0f, 3.0f, -0.05f}};
@@ -112,8 +109,7 @@ class SceneSetupSimple {
         {{"TYPE", "staticmesh"}});
     mesh.Load();
 
-    auto mesh_handle = triangle->AddComponent<phx::MeshHandle>();
-    mesh_handle->SetMesh(mesh);
+    triangle->AddComponent<phx::ResourceComponent<phx::Mesh>>(mesh);
 
     phx::Entity* main_light = scene->CreateEntity();
     main_light->AddComponent<phx::Transform>();
diff --git a/tests/src/integration_test_rendering.cpp b/tests/src/integration_test_rendering.cpp
index 607b588d92db7d83bddd3a4933033188cafcdcac..0408ad9563589710342f134267aa0ab0bab83b6c 100644
--- a/tests/src/integration_test_rendering.cpp
+++ b/tests/src/integration_test_rendering.cpp
@@ -33,7 +33,7 @@
 #include "phx/display/display_system_window.hpp"
 #include "phx/display/window.hpp"
 #include "phx/rendering/backend/opengl_image_buffer_data.hpp"
-#include "phx/rendering/components/mesh_handle.hpp"
+#include "phx/rendering/components/resource_component.hpp"
 #include "phx/rendering/rendering_system.hpp"
 #include "phx/resources/resource_manager.hpp"
 #include "phx/resources/types/mesh.hpp"
@@ -88,8 +88,7 @@ void CreateTestTriangleComponent(phx::Entity* triangle) {
       {{"TYPE", "staticmesh"}});
   mesh.Load();
 
-  phx::MeshHandle* mesh_handle = triangle->AddComponent<phx::MeshHandle>();
-  mesh_handle->SetMesh(mesh);
+  triangle->AddComponent<phx::ResourceComponent<phx::Mesh>>(mesh);
 }
 
 SUPPRESS_WARNINGS_END
@@ -112,9 +111,7 @@ SCENARIO("We can render a simple triangle", "[phx][phx::Rendering]") {
         glm::vec3(), 500.0f);
 
     triangle->AddComponent<phx::Transform>();
-    phx::MaterialHandle* material_handle =
-        triangle->AddComponent<phx::MaterialHandle>();
-    material_handle->SetMaterial(material);
+    triangle->AddComponent<phx::ResourceComponent<phx::Material>>(material);
 
     WHEN("We render the scene") {
       rendering_system->Update(phx::FrameTimer::TimeInfo{});
diff --git a/tests/src/test_entity.cpp b/tests/src/test_entity.cpp
index a4182668389c3fe4cda81d0fbc404076c1830995..eb44b18ee4ff3c854809a2955a9aa77a1ca90394 100644
--- a/tests/src/test_entity.cpp
+++ b/tests/src/test_entity.cpp
@@ -22,9 +22,8 @@
 
 #include "catch/catch.hpp"
 
-#include "phx/core/component.hpp"
 #include "phx/core/entity.hpp"
-#include "phx/rendering/components/mesh_handle.hpp"
+#include "phx/rendering/components/transform.hpp"
 
 SCENARIO("An entity can keep track of components.", "[phx][phx::Entity]") {
   GIVEN("A new entity.") {
@@ -39,8 +38,7 @@ SCENARIO("An entity can keep track of components.", "[phx][phx::Entity]") {
     }
 
     WHEN("We add a component.") {
-      phx::MeshHandle* component_handle =
-          entity.AddComponent<phx::MeshHandle>();
+      phx::Transform* component_handle = entity.AddComponent<phx::Transform>();
 
       THEN("You get a valid handle.") { REQUIRE(component_handle != nullptr); }
 
@@ -54,11 +52,10 @@ SCENARIO("An entity can keep track of components.", "[phx][phx::Entity]") {
       }
 
       WHEN("We ask for the first mesh component.") {
-        phx::MeshHandle* mesh_handle =
-            entity.GetFirstComponent<phx::MeshHandle>();
+        auto comp_handle = entity.GetFirstComponent<phx::Transform>();
         THEN("We get the mesh component we added earlier.") {
-          REQUIRE(mesh_handle != nullptr);
-          REQUIRE(mesh_handle == component_handle);
+          REQUIRE(comp_handle != nullptr);
+          REQUIRE(comp_handle == component_handle);
         }
       }
 
diff --git a/tests/src/test_material.cpp b/tests/src/test_material.cpp
index 93eb5ccb3eb8442d7417c346af9bea174c996904..47815119165884e47a0c59c962ba019171dad68d 100644
--- a/tests/src/test_material.cpp
+++ b/tests/src/test_material.cpp
@@ -27,7 +27,7 @@
 
 #include "phx/core/component.hpp"
 #include "phx/core/logger.hpp"
-#include "phx/rendering/components/material_handle.hpp"
+#include "phx/resources/types/material.hpp"
 
 #include "test_utilities/glm_vec.hpp"
 
diff --git a/tests/src/test_openvr_controller_model_system.cpp b/tests/src/test_openvr_controller_model_system.cpp
index 1a90a5d68a079ee0d76f4d212626d0083e456326..aae3caa286ab807a7fe2870f95319946da7f83b2 100644
--- a/tests/src/test_openvr_controller_model_system.cpp
+++ b/tests/src/test_openvr_controller_model_system.cpp
@@ -34,11 +34,12 @@ SUPPRESS_WARNINGS_END
 
 #include "phx/core/entity.hpp"
 #include "phx/core/scene.hpp"
+#include "phx/display/display_system_openvr.hpp"
 #include "phx/input/device_system.hpp"
+#include "phx/input/openvr_controller_behavior.hpp"
 #include "phx/input/openvr_controller_model_system.hpp"
 #include "phx/input/vr_controller.hpp"
-#include "phx/rendering/components/material_handle.hpp"
-#include "phx/rendering/components/mesh_handle.hpp"
+#include "phx/rendering/components/resource_component.hpp"
 #include "phx/rendering/rendering_system.hpp"
 
 #include "mocks/opengl_mock.hpp"
@@ -103,8 +104,11 @@ SCENARIO(
         REQUIRE(controller_entities.size() == 2);
 
         for (auto entity : controller_entities) {
-          REQUIRE(entity->GetFirstComponent<phx::MeshHandle>() != nullptr);
-          REQUIRE(entity->GetFirstComponent<phx::MaterialHandle>() != nullptr);
+          REQUIRE(
+              entity->GetFirstComponent<phx::ResourceComponent<phx::Mesh>>() !=
+              nullptr);
+          REQUIRE(entity->GetFirstComponent<
+                      phx::ResourceComponent<phx::Material>>() != nullptr);
         }
 
         auto side0 = controller_entities[0]
diff --git a/tests/src/test_resource_pointer.cpp b/tests/src/test_resource_pointer.cpp
index 8a0c9e361ed76e402de7b9552845b73351e21f3c..1e80bb34b306537e47f08acedb982bde6c0ae474 100644
--- a/tests/src/test_resource_pointer.cpp
+++ b/tests/src/test_resource_pointer.cpp
@@ -22,10 +22,13 @@
 
 #include "catch/catch.hpp"
 
-#include "phx/resources/types/image.hpp"
+#include "phx/core/entity.hpp"
+#include "phx/rendering/components/resource_component.hpp"
 #include "phx/resources/resource_manager.hpp"
 #include "phx/resources/resource_pointer.hpp"
 #include "phx/resources/resource_utils.hpp"
+#include "phx/resources/types/image.hpp"
+#include "phx/resources/types/model.hpp"
 
 SCENARIO(
     "The resource pointer makes the underlying resource available through the "
@@ -87,3 +90,25 @@ SCENARIO(
     }
   }
 }
+SCENARIO("ResourcePointers can be used in a ResourceComponent") {
+  GIVEN("A resource pointer to an arbitrarily chosen model resource.") {
+    phx::ResourcePointer<phx::Model> resource_pointer =
+        phx::ResourceManager::instance().DeclareResource<phx::Model>(
+            phx::ResourceUtils::DeclarationFromFile("models/bunny.obj"));
+    resource_pointer.Load();
+    auto mesh_resource_pointer = resource_pointer->GetMeshes()[0];
+    phx::Entity entity;
+    WHEN("We add the mesh_resource_pointer as ResourceComponent") {
+      entity.AddComponent<phx::ResourceComponent<phx::Mesh>>(
+          mesh_resource_pointer);
+      THEN(
+          "the resouce pointer is in the ResourceComponent and can be obtained "
+          "using GetResourcePointer()") {
+        auto resource_component =
+            entity.GetFirstComponent<phx::ResourceComponent<phx::Mesh>>();
+        REQUIRE(resource_component->GetResourcePointer().Get() ==
+                mesh_resource_pointer.Get());
+      }
+    }
+  }
+}
diff --git a/tests/src/test_scene_loader.cpp b/tests/src/test_scene_loader.cpp
index fefb838b4ec2a5fc8a0fd742f22ce9d624b754b9..8256a2037e2ff25ba7bc9c28e3b8865232f31aa8 100644
--- a/tests/src/test_scene_loader.cpp
+++ b/tests/src/test_scene_loader.cpp
@@ -26,9 +26,11 @@
 
 #include "phx/core/entity.hpp"
 #include "phx/core/scene.hpp"
-#include "phx/rendering/components/mesh_handle.hpp"
+#include "phx/rendering/components/resource_component.hpp"
 #include "phx/rendering/components/transform.hpp"
 #include "phx/resources/loaders/scene_loader.hpp"
+#include "phx/resources/resource_pointer.hpp"
+#include "phx/resources/types/mesh.hpp"
 
 #include "mocks/opengl_mock.hpp"
 #include "trompeloeil.hpp"
@@ -61,7 +63,9 @@ SCENARIO("The scene loader can load a model", "[phx][phx::SceneLoader]") {
           if (currentEntity->GetName() == "2meshTest") {
             nameCounter++;
           }
-          if (currentEntity->GetFirstComponent<phx::MeshHandle>() != nullptr) {
+          if (currentEntity
+                  ->GetFirstComponent<phx::ResourceComponent<phx::Mesh>>() !=
+              nullptr) {
             auto parentEntity =
                 currentEntity->GetFirstComponent<phx::Transform>()
                     ->GetParent()