diff --git a/database/db.hpp b/database/db.hpp
index 230bcd9d8..77210b6da 100644
--- a/database/db.hpp
+++ b/database/db.hpp
@@ -11,4 +11,10 @@ public:
 
     Graph graph;
     tx::Engine tx_engine;
+
+    //  only for test purposes
+    std::string identifier()
+    {
+        return "memgraph";
+    }
 };
diff --git a/dc/dynamic_lib.hpp b/dc/dynamic_lib.hpp
index b33c432a7..c5baa3180 100644
--- a/dc/dynamic_lib.hpp
+++ b/dc/dynamic_lib.hpp
@@ -16,6 +16,15 @@ public:
     {
     }
 
+    //  TODO debug why this doesn't work
+    typename T::lib_object* instance()
+    {
+        //  TODO singleton, lazy, concurrency
+        this->load();
+        lib_object = this->produce_method();
+        return lib_object;
+    }
+
     void load()
     {
         load_lib();
@@ -23,9 +32,17 @@ public:
         load_destruct_func();
     }
 
+    ~DynamicLib()
+    {
+        if (lib_object != nullptr) {
+            destruct_method(lib_object);
+        }
+    }
+
 private:
     std::string lib_path;
     void *dynamic_lib;
+    typename T::lib_object* lib_object;
 
     void load_lib()
     {
diff --git a/query_engine/code_executor.hpp b/query_engine/code_executor.hpp
new file mode 100644
index 000000000..abcc5dbec
--- /dev/null
+++ b/query_engine/code_executor.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <string>
+
+#include "i_code_cpu.hpp"
+#include "database/db.hpp"
+
+class CodeExecutor
+{
+public:
+
+    void execute(ICodeCPU *code_cpu)
+    {
+        code_cpu->name();
+        code_cpu->run(db);
+    }
+
+private:
+    Db db;
+};
diff --git a/query_engine/code_loader.hpp b/query_engine/code_loader.hpp
new file mode 100644
index 000000000..3efb6c0a8
--- /dev/null
+++ b/query_engine/code_loader.hpp
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <string>
+#include <unordered_map>
+#include <memory>
+
+#include "memgraph_dynamic_lib.hpp"
+#include "query_stripper.hpp"
+#include "code_compiler.hpp"
+#include "code_generator.hpp"
+#include "utils/hashing/fnv.hpp"
+
+using std::string;
+using std::cout;
+using std::endl;
+
+class CodeLoader
+{    
+public:
+
+    using sptr_code_lib = std::shared_ptr<CodeLib>;
+
+    CodeLoader()
+        : stripper(make_query_stripper(TK_INT, TK_FLOAT, TK_STR))
+    {
+    }
+
+    ICodeCPU* load_code_cpu(const string& query)
+    {
+        //  TODO implement me
+        //  for now returns already compiled code
+
+        auto stripped = stripper.strip(query);
+        //  TODO move to logger
+        cout << "Stripped query is: " << stripped << endl;
+        auto stripped_hash = fnv(stripped);
+        //  TODO move to logger
+        cout << "Query hash is: " << stripped_hash << endl;
+        
+        auto code_lib = load_code_lib("./compiled/cpu/create_return.so");
+        code_libs.insert({{stripped_hash, code_lib}});
+
+        return code_lib->instance();
+    }
+
+private:
+    //  TODO somehow remove int.. from here
+    QueryStripper<int, int, int> stripper;
+    // TODO ifdef MEMGRAPH64 problem, how to use this kind
+    // of ifdef functions?
+    // uint64_t depends on fnv function
+    std::unordered_map<uint64_t, sptr_code_lib> code_libs;
+
+    CodeGenerator code_generator;
+    CodeCompiler code_compiler;
+
+    sptr_code_lib load_code_lib(const string& path)
+    {
+        sptr_code_lib code_lib = std::make_shared<CodeLib>(path);
+        code_lib->load();
+        return code_lib;
+    }
+};
diff --git a/query_engine/compile.sh b/query_engine/compile.sh
index 4a0d99391..7d67363ff 100755
--- a/query_engine/compile.sh
+++ b/query_engine/compile.sh
@@ -1,4 +1,7 @@
 #!/bin/bash
 
 # TODO: create Makefile or cmake script
-clang++ -std=c++1y -g -I../ main.cpp ../cypher/cypher.cpp -o engine
+cd compiled/cpu
+clang++ -std=c++1y create_return.cpp -o create_return.so -I../../../ -shared -fPIC
+cd ../..
+clang++ -std=c++1y -g -I../ main.cpp ../cypher/cypher.cpp -o engine -ldl
diff --git a/query_engine/compiled/cpu/create_return.cpp b/query_engine/compiled/cpu/create_return.cpp
new file mode 100644
index 000000000..968c23063
--- /dev/null
+++ b/query_engine/compiled/cpu/create_return.cpp
@@ -0,0 +1,33 @@
+#include <iostream>
+
+#include "query_engine/i_code_cpu.hpp"
+
+using std::cout;
+using std::endl;
+
+class CreateReturn : public ICodeCPU
+{
+public:
+
+    void name() const override
+    {
+        cout << "CRETE RETURN QUERY" << endl;
+    }
+
+    void run(Db& db) const override
+    {
+        cout << db.identifier() << endl;
+    }
+
+    ~CreateReturn() {}
+};
+
+extern "C" ICodeCPU* produce() 
+{
+    return new CreateReturn();
+}
+
+extern "C" void destruct(ICodeCPU* p) 
+{
+    delete p;
+}
diff --git a/query_engine/engine b/query_engine/engine
index 45665ba9a..ccb486170 100755
Binary files a/query_engine/engine and b/query_engine/engine differ
diff --git a/query_engine/i_code_cpu.hpp b/query_engine/i_code_cpu.hpp
new file mode 100644
index 000000000..ef25dbc42
--- /dev/null
+++ b/query_engine/i_code_cpu.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "database/db.hpp"
+
+class ICodeCPU
+{
+public:
+    virtual void name() const = 0;
+    virtual void run(Db& db) const = 0;
+    virtual ~ICodeCPU() {}
+};
+
+typedef ICodeCPU* (*produce_t)();
+typedef void (*destruct_t)(ICodeCPU*);
diff --git a/query_engine/memgraph_dynamic_lib.hpp b/query_engine/memgraph_dynamic_lib.hpp
new file mode 100644
index 000000000..7dbc07ed2
--- /dev/null
+++ b/query_engine/memgraph_dynamic_lib.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "i_code_cpu.hpp"
+#include "dc/dynamic_lib.hpp"
+
+class MemgraphDynamicLib
+{
+public:
+    const static std::string produce_name;
+    const static std::string destruct_name;
+    using produce = produce_t;
+    using destruct = destruct_t;
+    using lib_object = ICodeCPU;
+};
+const std::string MemgraphDynamicLib::produce_name = "produce";
+const std::string MemgraphDynamicLib::destruct_name = "destruct";
+
+using CodeLib = DynamicLib<MemgraphDynamicLib>;
diff --git a/query_engine/query_engine.hpp b/query_engine/query_engine.hpp
index 673422b33..086ac8702 100644
--- a/query_engine/query_engine.hpp
+++ b/query_engine/query_engine.hpp
@@ -1,49 +1,30 @@
 #pragma once
 
-#include <iostream>
-
-#include "query_stripper.hpp"
-#include "query_traverser.hpp"
-#include "code_generator.hpp"
-#include "code_compiler.hpp"
-#include "query_executor.hpp"
+#include "code_loader.hpp"
+#include "code_executor.hpp"
 #include "query_result.hpp"
-#include "utils/hashing/fnv.hpp"
-
-using std::cout;
-using std::endl;
 
 //
 // Current arhitecture:
-// query -> traverser -> [generator] -> [compiler] -> executor
+// query -> code_loader -> query_stripper -> [code_generator]
+// -> [code_compiler] -> code_executor
 //
 
 class QueryEngine
 {
 public:
     QueryEngine()
-        : stripper(make_query_stripper(TK_INT, TK_FLOAT, TK_STR))
     {
     }
 
-    QueryResult execute(const std::string& query)
+    QueryResult* execute(const std::string& query)
     {
-        cout << "QUERY ENGINE EXECUTE" << endl;
-        auto stripped = stripper.strip(query);
-        cout << "STRIPPED: " << stripped << endl;
-        auto stripped_hash = fnv(stripped);
-        cout << "STRIPPED HASH: " << stripped_hash << endl;
+        executor.execute(loader.load_code_cpu(query));
 
-        // traverser.build_tree(query);
-        // traverser.traverse();
-        return QueryResult();
+        throw std::runtime_error("implement me");
     }
 
 private:
-    // TODO: use IoC or something similar
-    QueryStripper<int, int, int> stripper;
-    QueryTraverser traverser;
-    CodeGenerator generator;
-    CodeCompiler compiler;
-    QueryExecutor executor;
+    CodeLoader loader;
+    CodeExecutor executor;
 };
diff --git a/query_engine/query_executor.hpp b/query_engine/query_executor.hpp
deleted file mode 100644
index 5aefbd39b..000000000
--- a/query_engine/query_executor.hpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-class QueryExecutor
-{
-};
diff --git a/query_engine/traverser/code_compiler.hpp b/query_engine/traverser/code_compiler.hpp
new file mode 100644
index 000000000..e69de29bb