diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 4fcc50b012eca626d4c98f84b3b9f195a8d3e8f1..e78586d085fb85ff875fa65ec817893afb380ac2 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -6,8 +6,9 @@
 
 #include <vulkan/vulkan.hpp>
 #include "vkcv/Context.hpp"
+#include "vkcv/SwapChain.hpp"
+#include "vkcv/Window.hpp"
 #include "vkcv/Handles.hpp"
-#include <GLFW/glfw3.h>
 
 namespace vkcv
 {
@@ -25,11 +26,14 @@ namespace vkcv
          *
          * @param context encapsulates various Vulkan objects
          */
-        explicit Core(Context &&context) noexcept;
+        Core(Context &&context, const Window &window, SwapChain &swapChain) noexcept;
         // explicit destruction of default constructor
         Core() = delete;
 
         Context m_Context;
+        SwapChain& m_swapchain;
+        const Window& m_window;
+
     public:
         /**
          * Destructor of #Core destroys the Vulkan objects contained in the core's context.
@@ -85,7 +89,8 @@ namespace vkcv
              * @param[in] deviceExtensions (optional) Requested device extensions
              * @return New instance of #Context
              */
-        static Core create(const char *applicationName,
+        static Core create(const Window &window,
+                           const char *applicationName,
                            uint32_t applicationVersion,
                            uint32_t queueCount,
                            std::vector<vk::QueueFlagBits> queueFlags    = {},
@@ -98,30 +103,4 @@ namespace vkcv
         PipelineHandle createPipeline(const Pipeline &pipeline);
 
     };
-
-    /**
-     * initializes glfw once and increases the counter
-     */
-    void initGLFW();
-
-    /**
-     * terminates glfw once, if it was initialized or decreases the counter
-     */
-    void terminateGLFW();
-
-    /**
-     * gets the window width
-     * @param window glfwWindow
-     * @return int with window width
-     */
-    [[nodiscard]]
-    int getWidth(GLFWwindow *window);
-
-    /**
-     * gets the window height
-     * @param window glfwWindow
-     * @return int with window height
-     */
-    [[nodiscard]]
-    int getHeight(GLFWwindow *window);
 }
diff --git a/include/vkcv/SwapChain.hpp b/include/vkcv/SwapChain.hpp
index 35d3eb3e9ab7458dffd4e27d7984b396f9faf8a7..42e408b9e75ed20252594878feee8aa4b04c24a5 100644
--- a/include/vkcv/SwapChain.hpp
+++ b/include/vkcv/SwapChain.hpp
@@ -1,7 +1,7 @@
 #pragma once
 #include "vulkan/vulkan.hpp"
-#include "Core.hpp"
-#include <GLFW/glfw3.h>
+#include "Context.hpp"
+#include "vkcv/Window.hpp"
 #include <iostream>
 
 
@@ -13,10 +13,10 @@ namespace vkcv {
     private:
 
         vk::SurfaceKHR m_surface;
-        const vkcv::Core* m_core;
+        const vkcv::Context& m_context;
 		vk::SwapchainKHR m_swapchain;
 		
-        SwapChain(vk::SurfaceKHR surface, const vkcv::Core* core, vk::SwapchainKHR swapchain);
+        SwapChain(vk::SurfaceKHR surface, const vkcv::Context &context, vk::SwapchainKHR swapchain);
 
     public:
         // bin mir grade unsicher wegen der Mehrfachinstanziierung der Klasse
@@ -31,7 +31,7 @@ namespace vkcv {
         [[nodiscard]]
         vk::SwapchainKHR getSwapchain();
 
-        static SwapChain create(GLFWwindow *window, const vkcv::Core* core);
+        static SwapChain create(const Window &window, const Context &context);
        
         virtual ~SwapChain();
     };
diff --git a/include/vkcv/Window.hpp b/include/vkcv/Window.hpp
index 43fce827bf2da863a843e933e52c3704dfdf06b6..ef5e35cc10a9983440d3d33f7d8dd93a6aef5199 100644
--- a/include/vkcv/Window.hpp
+++ b/include/vkcv/Window.hpp
@@ -4,10 +4,7 @@
  * @file src/vkcv/Window.hpp
  * @brief Window class to handle a basic rendering surface and input
  */
-
-#define GLFW_INCLUDE_VULKAN
 #include <GLFW/glfw3.h>
-#include "SwapChain.hpp"
 
 #define NOMINMAX
 #include <algorithm>
@@ -17,13 +14,12 @@ namespace vkcv {
     private:
         GLFWwindow *m_window;
 
-        const vkcv::SwapChain* m_swapChain;
 
         /**
          *
          * @param GLFWwindow of the class
          */
-        Window(GLFWwindow *window, const vkcv::SwapChain *swapChain);
+        explicit Window(GLFWwindow *window);
 
     public:
         /**
@@ -34,7 +30,7 @@ namespace vkcv {
          * @param[in] resizable resize ability of the window (optional)
          * @return Window class
          */
-        static Window create(const vkcv::Core& core, const char *windowTitle, int width = -1, int height = -1, bool resizable = false);
+        static Window create( const char *windowTitle, int width = -1, int height = -1, bool resizable = false);
         /**
          * checks if the window is still open, or the close event was called
          * This function should be changed/removed later on
@@ -71,10 +67,25 @@ namespace vkcv {
          */
         Window &operator=(Window &&other) = default;
 
+        /**
+         * gets the window width
+         * @param window glfwWindow
+         * @return int with window width
+         */
+        [[nodiscard]]
+        int getWidth() const;
+
+        /**
+         * gets the window height
+         * @param window glfwWindow
+         * @return int with window height
+         */
+        [[nodiscard]]
+        int getHeight() const;
+
         /**
          * Destructor of #Window, terminates GLFW
          */
         virtual ~Window();
-
     };
 }
\ No newline at end of file
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index ab11172802cb8d32f49eef0dae0bf611c61314a3..0136179b3aca160a7e912702987fe7a95dcdb428 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -1,11 +1,18 @@
 #include <iostream>
 #include <vkcv/Core.hpp>
-#include <vkcv/Window.hpp>
 
 int main(int argc, const char** argv) {
     const char* applicationName = "First Triangle";
-    
+
+    vkcv::Window window = vkcv::Window::create(
+            applicationName,
+            800,
+            600,
+            false
+    );
+
 	vkcv::Core core = vkcv::Core::create(
+            window,
             applicationName,
 		VK_MAKE_VERSION(0, 0, 1),
 		20,
@@ -18,15 +25,6 @@ int main(int argc, const char** argv) {
 	const vk::Instance& instance = context.getInstance();
 	const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice();
 	const vk::Device& device = context.getDevice();
-	
-    vkcv::Window window = vkcv::Window::create(
-            core,
-            applicationName,
-            800,
-            600,
-            false
-    );
-
 
 	std::cout << "Physical device: " << physicalDevice.getProperties().deviceName << std::endl;
 
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 9f28db42e89af1707b4cf493340aa56e070e1307..b36e2d94d9903cca4fb0c38115b9cd5b3bac1f7e 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -178,14 +178,14 @@ namespace vkcv
         return -1;
     }
 
-    Core Core::create(const char *applicationName,
+    Core Core::create(const Window &window,
+                      const char *applicationName,
                       uint32_t applicationVersion,
                       uint32_t queueCount,
                       std::vector<vk::QueueFlagBits> queueFlags,
                       std::vector<const char *> instanceExtensions,
                       std::vector<const char *> deviceExtensions)
     {
-        vkcv::initGLFW();
         // check for layer support
 
         const std::vector<vk::LayerProperties>& layerProperties = vk::enumerateInstanceLayerProperties();
@@ -307,7 +307,8 @@ namespace vkcv
 
         Context context(instance, physicalDevice, device);
 
-        return Core(std::move(context));
+        SwapChain swapChain = SwapChain::create(window, context);
+        return Core(std::move(context) , window, swapChain);
     }
 
     const Context &Core::getContext() const
@@ -315,40 +316,9 @@ namespace vkcv
         return m_Context;
     }
 
-    Core::Core(Context &&context) noexcept :
-            m_Context(std::move(context))
+    Core::Core(Context &&context, const Window &window , SwapChain &swapChain) noexcept :
+            m_Context(std::move(context)),
+            m_window(window),
+            m_swapchain(swapChain)
     {}
-
-    int glfwCounter = 0;
-
-    void initGLFW() {
-
-        if (glfwCounter == 0) {
-            int glfwSuccess = glfwInit();
-
-            if (glfwSuccess == GLFW_FALSE) {
-                throw std::runtime_error("Could not initialize GLFW");
-            }
-        }
-        glfwCounter++;
-    }
-
-    void terminateGLFW() {
-        if (glfwCounter == 1) {
-            glfwTerminate();
-        }
-        glfwCounter--;
-    }
-
-    int getWidth(GLFWwindow *window)  {
-        int width;
-        glfwGetWindowSize(window, &width, nullptr);
-        return width;
-    }
-
-    int getHeight(GLFWwindow *window)  {
-        int height;
-        glfwGetWindowSize(window, nullptr, &height);
-        return height;
-    }
 }
diff --git a/src/vkcv/SwapChain.cpp b/src/vkcv/SwapChain.cpp
index bcc51de659588bad8badd95343fb3957ffb63106..6bb3d229432fa4ef75c8890c30b6ce13faff7f90 100644
--- a/src/vkcv/SwapChain.cpp
+++ b/src/vkcv/SwapChain.cpp
@@ -3,9 +3,9 @@
 
 namespace vkcv {
 
-    SwapChain::SwapChain(vk::SurfaceKHR surface, const vkcv::Core* core, vk::SwapchainKHR swapchain)
-        : m_surface(surface), m_core(core), m_swapchain(swapchain)
-        {}
+    SwapChain::SwapChain(vk::SurfaceKHR surface, const vkcv::Context &context, vk::SwapchainKHR swapchain)
+        : m_surface(surface), m_context(context), m_swapchain(swapchain)
+    {}
 
     vk::SwapchainKHR SwapChain::getSwapchain() {
         return m_swapchain;
@@ -22,7 +22,7 @@ namespace vkcv {
         vk::Bool32 surfaceSupport = false;
         // ToDo: hierfuer brauchen wir jetzt den queuefamiliy Index -> siehe ToDo in Context.cpp
         // frage: nimmt die Swapchain automatisch den 0'ten Index (Graphics Queue Family)?
-        if (physicalDevice.getSurfaceSupportKHR(0, surface, &surfaceSupport) != vk::Result::eSuccess && surfaceSupport != true) {
+        if (physicalDevice.getSurfaceSupportKHR(0, vk::SurfaceKHR(surface), &surfaceSupport) != vk::Result::eSuccess && surfaceSupport != true) {
             throw std::runtime_error("surface is not supported by the device!");
         }
 
@@ -30,15 +30,15 @@ namespace vkcv {
     }
 
 
-    vk::Extent2D chooseSwapExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, GLFWwindow* window){
+    vk::Extent2D chooseSwapExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, const Window &window){
         vk::SurfaceCapabilitiesKHR surfaceCapabilities;
         if(physicalDevice.getSurfaceCapabilitiesKHR(surface,&surfaceCapabilities) != vk::Result::eSuccess){
             throw std::runtime_error("cannot get surface capabilities. There is an issue with the surface.");
         }
 
         VkExtent2D extent2D = {
-                static_cast<uint32_t>(vkcv::getWidth(window)),
-                static_cast<uint32_t>(vkcv::getHeight(window))
+                static_cast<uint32_t>(window.getWidth()),
+                static_cast<uint32_t>(window.getHeight())
         };
         extent2D.width = std::max(surfaceCapabilities.minImageExtent.width, std::min(surfaceCapabilities.maxImageExtent.width, extent2D.width));
         extent2D.height = std::max(surfaceCapabilities.minImageExtent.height, std::min(surfaceCapabilities.maxImageExtent.height, extent2D.height));
@@ -99,13 +99,12 @@ namespace vkcv {
         return imageCount;
     }
 
-    SwapChain SwapChain::create(GLFWwindow* window, const vkcv::Core* core) {
+    SwapChain SwapChain::create(const Window &window, const Context &context) {
+        const vk::Instance& instance = context.getInstance();
+        const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice();
+        const vk::Device& device = context.getDevice();
 
-        const vk::Instance& instance = core->getContext().getInstance();
-        const vk::PhysicalDevice& physicalDevice = core->getContext().getPhysicalDevice();
-        const vk::Device& device = core->getContext().getDevice();
-
-        vk::SurfaceKHR surface = createSurface(window,instance,physicalDevice);
+        vk::SurfaceKHR surface = createSurface(window.getWindow(),instance,physicalDevice);
 
         vk::Extent2D extent2D = chooseSwapExtent(physicalDevice, surface, window);
         vk::SurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(physicalDevice, surface);
@@ -133,14 +132,13 @@ namespace vkcv {
 
         vk::SwapchainKHR swapchain = device.createSwapchainKHR(swapchainCreateInfo);
 
-        return SwapChain(surface, core, swapchain);
-
+        return SwapChain(surface, context, swapchain);
     }
 
 
     SwapChain::~SwapChain() {
-        m_core->getContext().getDevice().destroySwapchainKHR( m_swapchain );
-        m_core->getContext().getInstance().destroySurfaceKHR( m_surface );
+        m_context.getDevice().destroySwapchainKHR( m_swapchain );
+        m_context.getInstance().destroySurfaceKHR( m_surface );
     }
 
 }
diff --git a/src/vkcv/Window.cpp b/src/vkcv/Window.cpp
index 962e8ccaa3276997dd5979235b32b9c6ae98b714..ce05d67cb216215c625b468acdb85be2fc2a8b2e 100644
--- a/src/vkcv/Window.cpp
+++ b/src/vkcv/Window.cpp
@@ -11,20 +11,23 @@ namespace vkcv {
 
     static uint32_t s_WindowCount = 0;
 
-    Window::Window(GLFWwindow *window, const vkcv::SwapChain *swapChain)
-            : m_window(window), m_swapChain(swapChain) {
+    Window::Window(GLFWwindow *window)
+            : m_window(window) {
     }
 
     Window::~Window() {
         glfwDestroyWindow(m_window);
         s_WindowCount--;
 
-        terminateGLFW();
+        if(s_WindowCount == 0) {
+            glfwTerminate();
+        }
     }
 
-    Window Window::create(const vkcv::Core& core, const char *windowTitle, int width, int height, bool resizable) {
-        initGLFW();
-
+    Window Window::create( const char *windowTitle, int width, int height, bool resizable) {
+        if(s_WindowCount == 0) {
+            glfwInit();
+        }
         s_WindowCount++;
 
         width = std::max(width, 1);
@@ -35,11 +38,7 @@ namespace vkcv {
         GLFWwindow *window;
         window = glfwCreateWindow(width, height, windowTitle, nullptr, nullptr);
 
-       const vkcv::SwapChain swapChain = vkcv::SwapChain::create(
-                window,
-                &core);
-
-        return Window(window, &swapChain);
+        return Window(window);
     }
 
     bool Window::isWindowOpen() const {
@@ -50,6 +49,18 @@ namespace vkcv {
         glfwPollEvents();
     }
 
+    int Window::getWidth() const {
+        int width;
+        glfwGetWindowSize(m_window, &width, nullptr);
+        return width;
+    }
+
+    int Window::getHeight() const {
+        int height;
+        glfwGetWindowSize(m_window, nullptr, &height);
+        return height;
+    }
+
     GLFWwindow *Window::getWindow() const {
         return m_window;
     }