diff --git a/src/main.cpp b/src/main.cpp
index 334c6ed..a61fb67 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -4,6 +4,8 @@
 
 #include <iostream>
 #include <vector>
+#include <array>
+#include <set>
 #include <memory>
 #include <stdexcept>
 
@@ -19,8 +21,21 @@ public:
 private:
     /////////////////////////////////////////////////////////////////
     /// static values
     static constexpr uint32_t WIDTH = 800;
     static constexpr uint32_t HEIGHT = 600;
+
+    inline static const std::vector<const char*> validationLayers {
+        "VK_LAYER_KHRONOS_validation"
+    };
+
+    #ifdef NDEBUG
+        static constexpr bool enableValidationLayers = false;
+    #else
+        static constexpr bool enableValidationLayers = true;
+    #endif
     /////////////////////////////////////////////////////////////////
 
     /////////////////////////////////////////////////////////////////
@@ -28,6 +43,7 @@ private:
     GLFWwindow* m_window{ nullptr };
     vk::raii::Context m_context;
     vk::raii::Instance m_instance{ nullptr };
+    vk::raii::DebugUtilsMessengerEXT m_debugMessenger{ nullptr };
     /////////////////////////////////////////////////////////////////
 
     /////////////////////////////////////////////////////////////////
@@ -43,6 +59,7 @@ private:
 
     void initVulkan() {
         createInstance();
+        setupDebugMessenger();
     }
 
     void mainLoop() {
@@ -59,7 +76,25 @@ private:
 
     /////////////////////////////////////////////////////////////////
     /// instance creation
+    std::vector<const char*> getRequiredExtensions() {
+        uint32_t glfwExtensionCount = 0;
+        const char** glfwExtensions;
+        glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
+
+        std::vector<const char*> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
+
+        if (enableValidationLayers) {
+            extensions.emplace_back( VK_EXT_DEBUG_UTILS_EXTENSION_NAME );
+        }
+        extensions.emplace_back( VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME );
+
+        return extensions;
+    }
     void createInstance(){
+        if (enableValidationLayers && !checkValidationLayerSupport()) {
+            throw std::runtime_error("validation layers requested, but not available!");
+        }
+
         vk::ApplicationInfo applicationInfo( 
             "Hello Triangle",   // pApplicationName
             1,                  // applicationVersion
@@ -73,16 +108,18 @@ private:
             &applicationInfo    // vk::ApplicationInfo*
         );
 
-        uint32_t glfwExtensionCount = 0;
-        const char** glfwExtensions;
-        glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
-        std::vector<const char*> requiredExtensions( glfwExtensions, glfwExtensions + glfwExtensionCount );
-
-        requiredExtensions.emplace_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
-
+        std::vector<const char*> requiredExtensions = getRequiredExtensions();
+        // special setter
         createInfo.setPEnabledExtensionNames( requiredExtensions );
         createInfo.flags |= vk::InstanceCreateFlagBits::eEnumeratePortabilityKHR;
 
+        // vk::DebugUtilsMessengerCreateInfoEXT
+        auto debugMessengerCreateInfo = populateDebugMessengerCreateInfo();
+        if (enableValidationLayers) {
+            createInfo.setPEnabledLayerNames( validationLayers );
+            createInfo.pNext = &debugMessengerCreateInfo;
+        }
+
         auto extensions = m_context.enumerateInstanceExtensionProperties();
         std::cout << "available extensions:\n";
 
@@ -93,6 +130,47 @@ private:
         m_instance = m_context.createInstance( createInfo );
     }
     /////////////////////////////////////////////////////////////////
+
+    /////////////////////////////////////////////////////////////////
+    /// validation layer
+    static VKAPI_ATTR VkBool32 VKAPI_CALL debugMessageFunc( 
+        vk::DebugUtilsMessageSeverityFlagBitsEXT       messageSeverity,
+        vk::DebugUtilsMessageTypeFlagsEXT              messageTypes,
+        vk::DebugUtilsMessengerCallbackDataEXT const * pCallbackData,
+        void * pUserData ) {
+
+        std::cerr << "validation layer: " << pCallbackData->pMessage << std::endl;
+
+        return false;
+    }
+    bool checkValidationLayerSupport() {
+        auto layers = m_context.enumerateInstanceLayerProperties();
+        std::set<std::string> t_requiredLayers( validationLayers.begin(), validationLayers.end() );
+        for (const auto& layer : layers) {
+            t_requiredLayers.erase( layer.layerName );
+        }
+        return t_requiredLayers.empty();
+    }
+    vk::DebugUtilsMessengerCreateInfoEXT populateDebugMessengerCreateInfo() {
+        vk::DebugUtilsMessageSeverityFlagsEXT severityFlags( 
+            vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
+            vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
+            vk::DebugUtilsMessageSeverityFlagBitsEXT::eError 
+        );
+        vk::DebugUtilsMessageTypeFlagsEXT    messageTypeFlags( 
+            vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |         
+            vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance |
+            vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation 
+        );
+        return vk::DebugUtilsMessengerCreateInfoEXT ( {}, severityFlags, messageTypeFlags, &debugMessageFunc );
+    }
+    void setupDebugMessenger(){
+        if (!enableValidationLayers) return;
+
+        auto createInfo = populateDebugMessengerCreateInfo();
+        m_debugMessenger = m_instance.createDebugUtilsMessengerEXT( createInfo );
+    }
+    /////////////////////////////////////////////////////////////////
 };
 
 int main() {
