diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..78609aefac4b1681829f2d8ac66fd1b778d2787d
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.mako text eol=lf
diff --git a/.travis.yml b/.travis.yml
index b4f040ec2ad66772a06f5a2026642f18b93278e2..a33377b7d64100817b8783e08ed4e17793263ac1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,5 +10,5 @@ script:
  - cd example
  - python setup.py test
 install:
- - pip install Cython
+ - pip install Cython mako
  - python setup.py install
diff --git a/MANIFEST.in b/MANIFEST.in
index 5b2a10f6436e7e872a60783ac226cd7dd05ec924..901b33197d29e68ddd60768cfb46c6fbf0748ec8 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,4 @@
 include LICENSE
 include README.md
 include CONTRIBUTORS.md
-include snakehouse/*.template
+include snakehouse/templates/*.mako
diff --git a/setup.py b/setup.py
index c797b8e32debb9395a8e70fdca578bd61348c1f3..3a0c0731896fa1aa636ee40b2d875270ede49b17 100644
--- a/setup.py
+++ b/setup.py
@@ -6,11 +6,11 @@ setup(keywords=['cython', 'extension', 'multiple', 'pyx'],
       packages=find_packages(include=['snakehouse']),
       version=__version__,
       install_requires=[
-            'Cython'
+            'Cython', 'mako'
       ],
       python_requires='!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*',
       package_data={
-            'snakehouse': ['*.template']
+            'snakehouse': ['templates/*.mako']
       },
       package_dir={'snakehouse': 'snakehouse'},
       )
diff --git a/snakehouse/cdef.template b/snakehouse/cdef.template
deleted file mode 100644
index 0ff30ea3714eb10a2926a4eb42de5bac1d5f7d22..0000000000000000000000000000000000000000
--- a/snakehouse/cdef.template
+++ /dev/null
@@ -1,2 +0,0 @@
-cdef extern from "%s":
-    object PyInit_%s()
diff --git a/snakehouse/constants.py b/snakehouse/constants.py
deleted file mode 100644
index ff692348da9aa90b284df34b80e519d232d9753a..0000000000000000000000000000000000000000
--- a/snakehouse/constants.py
+++ /dev/null
@@ -1,18 +0,0 @@
-import logging
-import typing as tp
-
-logger = logging.getLogger(__name__)
-
-
-BOOTSTRAP_PYX_GET_DEFINITION_IF = """    if name == %s:
-        return %s
-"""
-
-BOOTSTRAP_PYX_GET_DEFINITION_ELIF = """    elif name == %s:
-        return %s
-"""
-
-INCLUDE_PYTHON_H = '#include "Python.h"\n'
-
-INCLUDE_PYINIT = 'PyObject* PyInit_%s(void);'
-
diff --git a/snakehouse/initpy.template b/snakehouse/initpy.template
deleted file mode 100644
index 20a09167ca8d172a4e29a7e3e5df17ba862e9f8a..0000000000000000000000000000000000000000
--- a/snakehouse/initpy.template
+++ /dev/null
@@ -1,2 +0,0 @@
-from {module_name}.__bootstrap__ import bootstrap_cython_submodules
-bootstrap_cython_submodules()
diff --git a/snakehouse/multibuild.py b/snakehouse/multibuild.py
index 2cda25fbec87f0b7474c30c15985ce80d74abe94..48de6ba1c35695ac4eaa3c7f49b70b3db5800a15 100644
--- a/snakehouse/multibuild.py
+++ b/snakehouse/multibuild.py
@@ -1,8 +1,19 @@
 import os
+import collections
 import pkg_resources
+from mako.template import Template
 from setuptools import Extension
-from .constants import BOOTSTRAP_PYX_GET_DEFINITION_IF, \
-    BOOTSTRAP_PYX_GET_DEFINITION_ELIF, INCLUDE_PYTHON_H, INCLUDE_PYINIT
+
+CdefSection = collections.namedtuple('CdefSection', ('h_file_name', 'module_name'))
+GetDefinitionSection = collections.namedtuple('GetDefinitionSection', (
+    'module_name', 'pyinit_name'
+))
+
+
+def render_mako(template_name: str, **kwargs) -> str:
+    tpl = Template(pkg_resources.resource_string(
+        'snakehouse', os.path.join('templates', template_name)).decode('utf8'))
+    return tpl.render(**kwargs)
 
 
 class Multibuild:
@@ -34,25 +45,21 @@ class Multibuild:
 
             module_name = name.replace('.pyx', '')
             h_name = name.replace('.pyx', '.h')
-            exported_line = INCLUDE_PYINIT % (module_name,)
 
             if os.path.exists(h_name):
                 with open(os.path.join(path, h_name), 'r') as f_in:
                     data = f_in.read()
 
-                if INCLUDE_PYTHON_H not in data:
-                    data = INCLUDE_PYTHON_H+data
-
-                if exported_line not in data:
-                    data = data+'\n'+exported_line+'\n'
+                if 'PyObject* PyInit_' not in data:
+                    data = render_mako('hfile.mako', initpy_name=module_name) + data
             else:
-                data = INCLUDE_PYTHON_H+'\n'+exported_line+'\n'
+                data = render_mako('hfile.mako', initpy_name=module_name)
 
             with open(os.path.join(path, h_name), 'w') as f_out:
                 f_out.write(data)
 
     def generate_bootstrap(self) -> str:
-        bootstrap_contents = pkg_resources.resource_string('snakehouse', 'bootstrap.template').decode('utf8')
+
         cdef_section = []
         for filename in self.pyx_files:
             path, name = os.path.split(filename)
@@ -64,8 +71,7 @@ class Multibuild:
                     replace('\\', '\\\\')
             else:
                 h_path_name = name.replace('.pyx', '.h')
-            cdef_template = pkg_resources.resource_string('snakehouse', 'cdef.template').decode('utf8')
-            cdef_section.append(cdef_template % (h_path_name, module_name))
+            cdef_section.append(CdefSection(h_path_name, module_name))
 
             if path:
                 complete_module_name = self.extension_name+'.'+'.'.join(path[1:].split(
@@ -73,27 +79,21 @@ class Multibuild:
             else:
                 complete_module_name = self.extension_name + '.'+module_name
 
-            self.modules.add((complete_module_name, 'PyInit_%s()' % (module_name, )))
+            self.modules.add((complete_module_name, module_name, ))
 
         get_definition = []
-        modules = iter(self.modules)
-        mod_name, init_fun_name = next(modules)
-        get_definition.append(BOOTSTRAP_PYX_GET_DEFINITION_IF % (repr(mod_name), init_fun_name))
-        for mod_name, init_fun_name in modules:
-            get_definition.append(BOOTSTRAP_PYX_GET_DEFINITION_ELIF % (
-                repr(mod_name), init_fun_name))
+        for mod_name, init_fun_name in self.modules:
+            get_definition.append(GetDefinitionSection(mod_name, init_fun_name))
 
-        return bootstrap_contents.format(cdef_section=''.join(cdef_section),
-                                         get_definition_section=''.join(get_definition),
-                                         module_set=repr(set(x[0] for x in self.modules)))
+        return render_mako('bootstrap.mako', cdef_sections=cdef_section,
+                                             get_definition_sections=get_definition,
+                                             module_set=repr(set(x[0] for x in self.modules)))
 
     def write_bootstrap_file(self):
         with open(os.path.join(self.bootstrap_directory, '__bootstrap__.pyx'), 'w') as f_out:
             f_out.write(self.generate_bootstrap())
 
     def alter_init(self):
-        pyinit_contents = pkg_resources.resource_string('snakehouse', 'initpy.template').decode('utf8')
-
         if os.path.exists(os.path.join(self.bootstrap_directory, '__init__.py')):
             with open(os.path.join(self.bootstrap_directory, '__init__.py'), 'r') as f_in:
                 data = f_in.read()
@@ -101,7 +101,7 @@ class Multibuild:
             data = ''
 
         if 'bootstrap_cython_submodules' not in data:
-            data = pyinit_contents.format(module_name=self.extension_name) + data
+            data = render_mako('initpy.mako', module_name=self.extension_name) + data
 
         with open(os.path.join(self.bootstrap_directory, '__init__.py'), 'w') as f_out:
             f_out.write(data)
diff --git a/snakehouse/bootstrap.template b/snakehouse/templates/bootstrap.mako
similarity index 73%
rename from snakehouse/bootstrap.template
rename to snakehouse/templates/bootstrap.mako
index 2df11b8002e94239c572027e5fd049272a25e79c..508cb0f70e04988ebced27ff1facd0b58675bf0f 100644
--- a/snakehouse/bootstrap.template
+++ b/snakehouse/templates/bootstrap.mako
@@ -6,10 +6,21 @@ cdef extern from "Python.h":
     object PyModule_FromDefAndSpec(PyModuleDef *definition, object spec)
     int PyModule_ExecDef(object module, PyModuleDef* definition)
 
-{cdef_section}
+% for cdef_section in cdef_sections:
+cdef extern from "${cdef_section.h_file_name}":
+    object PyInit_${cdef_section.module_name}()
+% endfor
 
 cdef object get_definition_by_name(str name):
-{get_definition_section}
+% for i, getdef_section in enumerate(get_definition_sections):
+% if i == 0:
+    if name == "${getdef_section.module_name}":
+        return PyInit_${getdef_section.pyinit_name}()
+% else:
+    elif name == "${getdef_section.module_name}":
+        return PyInit_${getdef_section.pyinit_name}()
+% endif
+% endfor
 
 import sys
 
@@ -49,5 +60,5 @@ class CythonPackageMetaPathFinder:
         pass
 
 def bootstrap_cython_submodules():
-    modules_set = {module_set}
+    modules_set = ${module_set}
     sys.meta_path.append(CythonPackageMetaPathFinder(modules_set))
diff --git a/snakehouse/templates/hfile.mako b/snakehouse/templates/hfile.mako
new file mode 100644
index 0000000000000000000000000000000000000000..aee3bff7ad1e6aa6077af0a70b8baae8425b3587
--- /dev/null
+++ b/snakehouse/templates/hfile.mako
@@ -0,0 +1,3 @@
+#include "Python.h"
+
+PyObject* PyInit_${initpy_name}(void);
diff --git a/snakehouse/templates/initpy.mako b/snakehouse/templates/initpy.mako
new file mode 100644
index 0000000000000000000000000000000000000000..020fe76eeae514935ba3395ee559fa37bda17d8c
--- /dev/null
+++ b/snakehouse/templates/initpy.mako
@@ -0,0 +1,2 @@
+from ${module_name}.__bootstrap__ import bootstrap_cython_submodules
+bootstrap_cython_submodules()