diff --git a/config/Sources.cmake b/config/Sources.cmake
index 4f673e00d1e42e733534480d6085affd651a8c04..62cec249367995db0217c71455cfcee982c65af3 100644
--- a/config/Sources.cmake
+++ b/config/Sources.cmake
@@ -41,7 +41,6 @@ set(vkcv_sources
 		${vkcv_source}/vkcv/ShaderProgram.cpp
 
 		${vkcv_include}/vkcv/PipelineConfig.hpp
-		${vkcv_source}/vkcv/PipelineConfig.cpp
 
 		${vkcv_source}/vkcv/PipelineManager.hpp
 		${vkcv_source}/vkcv/PipelineManager.cpp
diff --git a/include/vkcv/PipelineConfig.hpp b/include/vkcv/PipelineConfig.hpp
index 729330fcaf7eeac2acfdd1816b86ac29c7d9e30b..93523128a67d7b9667c342fb7c10203f4b9a43dd 100644
--- a/include/vkcv/PipelineConfig.hpp
+++ b/include/vkcv/PipelineConfig.hpp
@@ -14,28 +14,9 @@
 namespace vkcv {
 
     struct PipelineConfig {
-        /**
-         *  Constructor for the pipeline. Creates a pipeline using @p vertexCode, @p fragmentCode as well as the
-         *  dimensions of the application window @p width and @p height. A handle for the Render Pass is also needed, @p passHandle.
-         *
-         * @param shaderProgram shaders of the pipeline
-         * @param height height of the application window
-         * @param width width of the application window
-         * @param passHandle handle for render pass
-         * @param vertexLayout layout of vertex buffer, comprised of its bindings and the bindings' attachments
-         */
-        PipelineConfig(
-            const ShaderProgram&                        shaderProgram,
-            uint32_t                                    width,
-            uint32_t                                    height,
-            const PassHandle                            &passHandle,
-            const VertexLayout                          &vertexLayouts,
-            const std::vector<vk::DescriptorSetLayout>  &descriptorLayouts,
-            bool                                        useDynamicViewport);
-
         ShaderProgram                         m_ShaderProgram;
-        uint32_t                              m_Height;
         uint32_t                              m_Width;
+		uint32_t                              m_Height;
         PassHandle                            m_PassHandle;
         VertexLayout                          m_VertexLayout;
         std::vector<vk::DescriptorSetLayout>  m_DescriptorLayouts;
diff --git a/projects/cmd_sync_test/src/main.cpp b/projects/cmd_sync_test/src/main.cpp
index a02c4542c7608e520e5ed33e746b5a9c836fc09f..81e9c1e61ed4e46f360d558f93730da4d095ac08 100644
--- a/projects/cmd_sync_test/src/main.cpp
+++ b/projects/cmd_sync_test/src/main.cpp
@@ -119,14 +119,16 @@ int main(int argc, const char** argv) {
 	std::vector<vkcv::DescriptorBinding> descriptorBindings = { firstMeshProgram.getReflectedDescriptors()[0] };
 	vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings);
 
-	const vkcv::PipelineConfig firstMeshPipelineConfig(
+	const vkcv::PipelineConfig firstMeshPipelineConfig {
         firstMeshProgram,
 		windowWidth,
 		windowHeight,
         firstMeshPass,
-        {firstMeshLayout},
+        firstMeshLayout,
 		{ core.getDescriptorSet(descriptorSet).layout },
-		true);
+		true
+	};
+	
 	vkcv::PipelineHandle firstMeshPipeline = core.createGraphicsPipeline(firstMeshPipelineConfig);
 	
 	if (!firstMeshPipeline) {
@@ -192,14 +194,16 @@ int main(int argc, const char** argv) {
 
 	const uint32_t shadowMapResolution = 1024;
 	const vkcv::Image shadowMap = core.createImage(shadowMapFormat, shadowMapResolution, shadowMapResolution, 1);
-	const vkcv::PipelineConfig shadowPipeConfig(
+	const vkcv::PipelineConfig shadowPipeConfig {
 		shadowShader, 
 		shadowMapResolution, 
 		shadowMapResolution, 
 		shadowPass,
-        {firstMeshLayout},
-		{}, 
-		false);
+        firstMeshLayout,
+		{},
+		false
+	};
+	
 	const vkcv::PipelineHandle shadowPipe = core.createGraphicsPipeline(shadowPipeConfig);
 
 	struct LightInfo {
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 42b1f595dc9f36f8cfb9816a1508980aefb52a83..afaf29d433bc0b14bd5be802957323947f46cd15 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -102,14 +102,15 @@ int main(int argc, const char** argv) {
 	std::vector<vkcv::DescriptorBinding> descriptorBindings = { firstMeshProgram.getReflectedDescriptors()[setID] };
 	vkcv::DescriptorSetHandle descriptorSet = core.createDescriptorSet(descriptorBindings);
 
-	const vkcv::PipelineConfig firstMeshPipelineConfig(
+	const vkcv::PipelineConfig firstMeshPipelineConfig {
         firstMeshProgram,
         UINT32_MAX,
         UINT32_MAX,
         firstMeshPass,
         {firstMeshLayout},
 		{ core.getDescriptorSet(descriptorSet).layout },
-		true);
+		true
+	};
 	vkcv::PipelineHandle firstMeshPipeline = core.createGraphicsPipeline(firstMeshPipelineConfig);
 	
 	if (!firstMeshPipeline) {
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 8ecea2b69906b017b321e3ca6002761fb8ffdd7d..b7de727907bb1b52c343015e9f7b1b331759ed24 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -17,7 +17,13 @@ int main(int argc, const char** argv) {
 	);
 
 	window.initEvents();
-
+	
+	vkcv::camera::CameraManager cameraManager(window, windowWidth, windowHeight);
+	uint32_t camIndex = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
+	uint32_t camIndex2 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
+	
+	cameraManager.getCamera(camIndex).setPosition(glm::vec3(0, 0, -2));
+	
 	vkcv::Core core = vkcv::Core::create(
 		window,
 		applicationName,
@@ -95,14 +101,15 @@ int main(int argc, const char** argv) {
 	triangleShaderProgram.addShader(vkcv::ShaderStage::VERTEX, std::filesystem::path("shaders/vert.spv"));
 	triangleShaderProgram.addShader(vkcv::ShaderStage::FRAGMENT, std::filesystem::path("shaders/frag.spv"));
 
-	const vkcv::PipelineConfig trianglePipelineDefinition(
+	const vkcv::PipelineConfig trianglePipelineDefinition {
 		triangleShaderProgram,
 		(uint32_t)windowWidth,
 		(uint32_t)windowHeight,
 		trianglePass,
 		{},
 		{},
-		false);
+		false
+	};
 
 	vkcv::PipelineHandle trianglePipeline = core.createGraphicsPipeline(trianglePipelineDefinition);
 
@@ -158,12 +165,6 @@ int main(int argc, const char** argv) {
 	vkcv::DrawcallInfo drawcall(renderMesh, {});
 
 	const vkcv::ImageHandle swapchainInput = vkcv::ImageHandle::createSwapchainImageHandle();
-	
-    vkcv::camera::CameraManager cameraManager(window, windowWidth, windowHeight);
-    uint32_t camIndex = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT);
-    uint32_t camIndex2 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL);
-	
-	cameraManager.getCamera(camIndex).setPosition(glm::vec3(0, 0, -2));
 
 	while (window.isWindowOpen())
 	{
diff --git a/src/vkcv/PipelineConfig.cpp b/src/vkcv/PipelineConfig.cpp
deleted file mode 100644
index 3bd2a68cb86f167afecc551dbd664dee8a63eb08..0000000000000000000000000000000000000000
--- a/src/vkcv/PipelineConfig.cpp
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * @authors Mara Vogt, Mark Mints
- * @file src/vkcv/Pipeline.cpp
- * @brief Pipeline class to handle shader stages
- */
-
-#include "vkcv/PipelineConfig.hpp"
-
-namespace vkcv {
-
-    PipelineConfig::PipelineConfig(
-		const ShaderProgram&                        shaderProgram,
-		uint32_t                                    width,
-		uint32_t                                    height,
-		const PassHandle                            &passHandle,
-		const VertexLayout                          &vertexLayout,
-		const std::vector<vk::DescriptorSetLayout>  &descriptorLayouts,
-		bool                                        useDynamicViewport)
-		:
-		m_ShaderProgram(shaderProgram),
-		m_Height(height),
-		m_Width(width),
-		m_PassHandle(passHandle),
-		m_VertexLayout(vertexLayout),
-		m_DescriptorLayouts(descriptorLayouts),
-		m_UseDynamicViewport(useDynamicViewport)
-		{}
-}
diff --git a/src/vkcv/PipelineManager.cpp b/src/vkcv/PipelineManager.cpp
index 81b7525b160374915b1918c30870b05e619a30a4..949e5b9f713f3cac72d67b8a22cae46fc12aef0d 100644
--- a/src/vkcv/PipelineManager.cpp
+++ b/src/vkcv/PipelineManager.cpp
@@ -7,8 +7,7 @@ namespace vkcv
 
     PipelineManager::PipelineManager(vk::Device device) noexcept :
     m_Device{device},
-    m_Pipelines{},
-    m_Configs{}
+    m_Pipelines{}
     {}
 
     PipelineManager::~PipelineManager() noexcept
@@ -271,8 +270,7 @@ namespace vkcv
         m_Device.destroy(fragmentModule);
         
         const uint64_t id = m_Pipelines.size();
-        m_Pipelines.push_back({ vkPipeline, vkPipelineLayout });
-        m_Configs.push_back(config);
+        m_Pipelines.push_back({ vkPipeline, vkPipelineLayout, config });
         return PipelineHandle(id, [&](uint64_t id) { destroyPipelineById(id); });
     }
 
@@ -320,10 +318,17 @@ namespace vkcv
 		}
     }
 
-    const PipelineConfig &PipelineManager::getPipelineConfig(const PipelineHandle &handle) const
+    const PipelineConfig& PipelineManager::getPipelineConfig(const PipelineHandle &handle) const
     {
         const uint64_t id = handle.getId();
-        return m_Configs.at(id);
+        
+        if (id >= m_Pipelines.size()) {
+        	static PipelineConfig dummyConfig;
+			vkcv_log(LogLevel::ERROR, "Invalid handle");
+			return dummyConfig;
+        }
+        
+        return m_Pipelines[id].m_config;
     }
 
     PipelineHandle PipelineManager::createComputePipeline(
@@ -373,7 +378,7 @@ namespace vkcv
         m_Device.destroy(computeModule);
 
         const uint64_t id = m_Pipelines.size();
-        m_Pipelines.push_back({ vkPipeline, vkPipelineLayout });
+        m_Pipelines.push_back({ vkPipeline, vkPipelineLayout, PipelineConfig() });
 
         return PipelineHandle(id, [&](uint64_t id) { destroyPipelineById(id); });
     }
diff --git a/src/vkcv/PipelineManager.hpp b/src/vkcv/PipelineManager.hpp
index 634f5f4e6464532306e35fd10d9a1623df6ace16..b153eb4632b844e84b92953fe8abf6666a13e0c9 100644
--- a/src/vkcv/PipelineManager.hpp
+++ b/src/vkcv/PipelineManager.hpp
@@ -14,11 +14,11 @@ namespace vkcv
     	struct Pipeline {
 			vk::Pipeline m_handle;
 			vk::PipelineLayout m_layout;
+			PipelineConfig m_config;
     	};
     	
         vk::Device m_Device;
         std::vector<Pipeline> m_Pipelines;
-        std::vector<PipelineConfig> m_Configs;
         
         void destroyPipelineById(uint64_t id);