diff --git a/include/Lexesis/backend.h b/include/Lexesis/backend.h
new file mode 100644
index 0000000..cecc5fe
--- /dev/null
+++ b/include/Lexesis/backend.h
@@ -0,0 +1,31 @@
+#pragma once
+#ifndef LEXESIS_BACKEND_H
+#define LEXESIS_BACKEND_H
+
+#include "Lexesis/automata.h"
+#include "Lexesis/template.h"
+
+#include <functional>
+#include <string>
+
+namespace lxs {
+    class Backend {
+        public:
+            Backend();
+            virtual ~Backend();
+
+            virtual std::string getName() = 0;
+            virtual bool canProcessLang(std::string lang);
+
+            virtual void generateLexer(std::function<std::ostream&(std::string)> getOstreamForFileName, std::string lexerName, const DFA& dfa) = 0;
+
+        protected:
+            void doTemplate(std::ostream& out, std::string templateName, templ::TemplateContext context);
+
+        private:
+            std::string findTemplate(std::string templateName);
+    };
+}
+
+#endif //LEXESIS_BACKEND_H
+
diff --git a/include/Lexesis/backendmanager.h b/include/Lexesis/backendmanager.h
new file mode 100644
index 0000000..5821c86
--- /dev/null
+++ b/include/Lexesis/backendmanager.h
@@ -0,0 +1,23 @@
+#pragma once
+#ifndef LEXESIS_BACKENDMANAGER_H
+#define LEXESIS_BACKENDMANAGER_H
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace lxs {
+    class Backend;
+
+    class BackendManager {
+        public:
+            void registerBackend(std::unique_ptr<Backend> backend);
+
+            Backend* findBackendForLang(std::string lang);
+
+        private:
+            std::vector<std::unique_ptr<Backend> > m_backends;
+    };
+}
+
+#endif //LEXESIS_BACKENDMANAGER_H
diff --git a/include/Lexesis/template.h b/include/Lexesis/template.h
new file mode 100644
index 0000000..5f59c83
--- /dev/null
+++ b/include/Lexesis/template.h
@@ -0,0 +1,30 @@
+#pragma once
+#ifndef LEXESIS_TEMPLATE_H
+#define LEXESIS_TEMPLATE_H
+
+#include <map>
+#include <string>
+#include <vector>
+
+namespace lxs {
+namespace templ {
+    using TemplateContext = void*;
+
+    TemplateContext make_string(std::string);
+    TemplateContext make_map(std::map<std::string, TemplateContext>);
+    TemplateContext make_array(std::vector<TemplateContext>);
+
+    class Template {
+        public:
+            Template(std::string filename);
+            ~Template();
+
+            void render(std::ostream& out, TemplateContext& context);
+        private:
+            std::string m_filename;
+    };
+
+} //namespace templ
+} //namespace lxs
+
+#endif //LEXESIS_TEMPLATE_H
diff --git a/src/backend.cpp b/src/backend.cpp
new file mode 100644
index 0000000..bb6aad8
--- /dev/null
+++ b/src/backend.cpp
@@ -0,0 +1,23 @@
+#include "Lexesis/backend.h"
+#include "config.h"
+
+namespace lxs {
+    Backend::Backend()
+    {}
+
+    Backend::~Backend()
+    {}
+
+    bool Backend::canProcessLang(std::string /*lang*/) {
+        return false;
+    }
+
+    void Backend::doTemplate(std::ostream& out, std::string templateName, templ::TemplateContext context) {
+        templ::Template tpl(findTemplate(templateName));
+        tpl.render(out, context);
+    }
+
+    std::string Backend::findTemplate(std::string templateName) {
+        return DATADIR "templates/" + templateName;
+    }
+}
diff --git a/src/config.h.in b/src/config.h.in
new file mode 100644
index 0000000..561aa3e
--- /dev/null
+++ b/src/config.h.in
@@ -0,0 +1,6 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#define DATADIR "@CMAKE_INSTALL_PREFIX@/share/Lexesis/"
+
+#endif //CONFIG_H
diff --git a/src/template.cpp b/src/template.cpp
new file mode 100644
index 0000000..42bfe39
--- /dev/null
+++ b/src/template.cpp
@@ -0,0 +1,14 @@
+#include "Lexesis/template.h"
+
+namespace lxs {
+namespace templ {
+    Template::Template(std::string filename) : m_filename(filename)
+    {}
+
+    Template::~Template()
+    {}
+
+    void Template::render(std::ostream&, TemplateContext&)
+    {}
+}
+}