diff --git a/config/Sources.cmake b/config/Sources.cmake
index 11c1388e7429fca514b83eb9ed6e8e08d880bf99..0f2c2cf7019f07a44b5fd067f1b7fe38c4db5bc6 100644
--- a/config/Sources.cmake
+++ b/config/Sources.cmake
@@ -33,4 +33,7 @@ set(vkcv_sources
         
         ${vkcv_include}/vkcv/CommandResources.hpp
         ${vkcv_source}/vkcv/CommandResources.cpp
+        
+        ${vkcv_include}/vkcv/SyncResources.hpp
+        ${vkcv_source}/vkcv/SyncResources.cpp
 )
diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 24f541dfdda2a94603be91d66394d869e0252e49..7cdb50fc50d437e1ec443f9df71621551cb2a553 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -14,6 +14,7 @@
 #include "vkcv/Handles.hpp"
 #include "vkcv/PipelineConfig.hpp"
 #include "CommandResources.hpp"
+#include "SyncResources.hpp"
 
 namespace vkcv
 {
@@ -34,7 +35,7 @@ namespace vkcv
          * @param context encapsulates various Vulkan objects
          */
         Core(Context &&context, const Window &window, SwapChain swapChain,  std::vector<vk::ImageView> imageViews, 
-			const CommandResources& commandResources) noexcept;
+			const CommandResources& commandResources, const SyncResources& syncResources) noexcept;
         // explicit destruction of default constructor
         Core() = delete;
 
@@ -51,6 +52,7 @@ namespace vkcv
         std::unique_ptr<PassManager> m_PassManager;
         std::unique_ptr<PipelineManager> m_PipelineManager;
 		CommandResources m_CommandResources;
+		SyncResources m_SyncResources;
     public:
         /**
          * Destructor of #Core destroys the Vulkan objects contained in the core's context.
diff --git a/include/vkcv/SyncResources.hpp b/include/vkcv/SyncResources.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..35e8c774837057e489999d69137af5567d1b0ff8
--- /dev/null
+++ b/include/vkcv/SyncResources.hpp
@@ -0,0 +1,12 @@
+#pragma once
+#include <vulkan/vulkan.hpp>
+
+namespace vkcv {
+	struct SyncResources {
+		vk::Semaphore renderFinished;
+		vk::Fence presentFinished;
+	};
+
+	SyncResources createDefaultSyncResources(const vk::Device& device);
+	void destroySyncResources(const vk::Device& device, const SyncResources& resources);
+}
\ No newline at end of file
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 2c9f4e6958a9cac6b0e115fcebe2964532262af3..03a3734d3260ba29d1f446b543672265e2c91779 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -452,8 +452,9 @@ namespace vkcv
 
 		const int graphicQueueFamilyIndex = queuePairsGraphics[0].first;
 		const auto defaultCommandResources = createDefaultCommandResources(context.getDevice(), graphicQueueFamilyIndex);
+		const auto defaultSyncResources = createDefaultSyncResources(context.getDevice());
 
-        return Core(std::move(context) , window, swapChain, imageViews, defaultCommandResources);
+        return Core(std::move(context) , window, swapChain, imageViews, defaultCommandResources, defaultSyncResources);
     }
 
     const Context &Core::getContext() const
@@ -462,7 +463,7 @@ namespace vkcv
     }
 
 	Core::Core(Context &&context, const Window &window , SwapChain swapChain,  std::vector<vk::ImageView> imageViews, 
-		const CommandResources& commandResources) noexcept :
+		const CommandResources& commandResources, const SyncResources& syncResources) noexcept :
 			m_Context(std::move(context)),
 			m_window(window),
 			m_swapchain(swapChain),
@@ -472,7 +473,8 @@ namespace vkcv
 			m_PipelineLayouts{},
 			m_PassManager{std::make_unique<PassManager>(m_Context.m_Device)},
 			m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)},
-			m_CommandResources(commandResources)
+			m_CommandResources(commandResources),
+			m_SyncResources(syncResources)
 	{}
 
 	Core::~Core() noexcept {
@@ -496,7 +498,8 @@ namespace vkcv
 			m_Context.m_Device.destroyImageView(image);
 		}
 
-		destroyCommandResources(m_Context.m_Device, m_CommandResources);
+		destroyCommandResources(m_Context.getDevice(), m_CommandResources);
+		destroySyncResources(m_Context.getDevice(), m_SyncResources);
 
 		m_Context.m_Device.destroySwapchainKHR(m_swapchain.getSwapchain());
 		m_Context.m_Instance.destroySurfaceKHR(m_swapchain.getSurface());
diff --git a/src/vkcv/SyncResources.cpp b/src/vkcv/SyncResources.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..71516da819b0c336653ff74c7e076597963f224b
--- /dev/null
+++ b/src/vkcv/SyncResources.cpp
@@ -0,0 +1,22 @@
+#include "vkcv/SyncResources.hpp"
+
+namespace vkcv {
+	SyncResources createDefaultSyncResources(const vk::Device& device) {
+		SyncResources resources;
+
+		const vk::SemaphoreCreateFlags semaphoreFlags = vk::SemaphoreCreateFlagBits();
+		const vk::SemaphoreCreateInfo semaphoreInfo(semaphoreFlags);
+		resources.renderFinished = device.createSemaphore(semaphoreInfo, nullptr, {});
+
+		const vk::FenceCreateFlags fenceFlags = vk::FenceCreateFlagBits();
+		vk::FenceCreateInfo fenceInfo(fenceFlags);
+		resources.presentFinished = device.createFence(fenceInfo, nullptr, {});
+
+		return resources;
+	}
+
+	void destroySyncResources(const vk::Device& device, const SyncResources& resources) {
+		device.destroySemaphore(resources.renderFinished);
+		device.destroyFence(resources.presentFinished);
+	}
+}
\ No newline at end of file