Mako

A fast, embedded-Python templating language that compiles templates directly into Python modules for near-native rendering speed.

Library
PyPI
v1.4.1
452stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
82/100Excellent
Development Activity80
Maintenance88
Community80
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
81/100Excellent
Architecture85
Code Quality78
Innovation74
Learning Curve88

Mako is a template library for Python that takes a different approach from most templating engines: instead of interpreting a template’s mini-language on every render, it compiles each template into an actual Python module the first time it is used, then imports and calls that module on subsequent renders. The result is a rendering engine that performs close to hand-written Python, while keeping a familiar Python Server Page-style syntax that borrows ideas from Django templates, Cheetah, Myghty, and Genshi.

Beyond raw speed, Mako gives templates the same expressive power as ordinary Python: arbitrary control-flow blocks, inline Python expressions, function-style <%def> blocks that can be called like functions or used as inheriting layout blocks, and full component/inheritance chains via <%inherit>. A caching layer (with a pluggable backend interface, including a Beaker integration) lets expensive fragments be memoized independently of the surrounding page.

Mako has quietly become foundational infrastructure rather than an end-user-facing tool: it is maintained by the SQLAlchemy project and used as the templating layer inside SQLAlchemy’s own documentation and code-generation tooling, and it has shipped for years as the default template engine in frameworks like Pyramid and Pylons, as well as historically inside large deployments such as Reddit. It also registers a Pygments lexer and a TurboGears templating-engine plugin out of the box, reflecting its role as embeddable infrastructure rather than a standalone product.

What You Get

  • Compile-to-Python rendering - templates are translated into real Python modules and cached on disk or in memory, so repeated renders skip re-parsing entirely.
  • Template inheritance and layout composition - <%inherit>, <%namespace>, and <%def> blocks let you build base layouts, override named blocks, and share fragments across templates.
  • Embedded Python control flow - %if, %for, and inline ${...} expressions give templates the full expressiveness of Python rather than a restricted templating mini-language.
  • Pluggable output filtering - built-in filters for HTML escaping, URL encoding, and trimming, plus the ability to define custom filters applied per-expression or per-<%def>.
  • Fragment-level caching - a Cache/CacheImpl abstraction with a default in-memory backend and an optional Beaker-backed implementation for memoizing expensive template sections.
  • Ecosystem integrations out of the box - a Pygments lexer for syntax highlighting, a TurboGears templating-engine entry point, and Babel/lingua-based i18n extraction plugins.

Common Use Cases

  • Server-rendered HTML in Python web apps - rendering page templates in frameworks like Pyramid or Pylons where Mako is a first-class, natively supported engine.
  • Documentation and code-generation tooling - generating structured text (docs, SQL, config files, generated source) where Mako’s Python-native control flow makes complex generation logic easier to express than in a restricted DSL.
  • High-throughput rendering paths - services that render the same templates repeatedly and benefit from Mako’s compile-once, execute-many-times model instead of paying interpretation cost on every request.
  • Layered page composition - building a shared site layout with <%inherit> and overriding specific content blocks per page, similar to Django or Jinja2 block-based inheritance.

Under The Hood

Architecture Mako is organized as a small compiler pipeline rather than a runtime interpreter: mako/lexer.py tokenizes template source into control and text regions, mako/parsetree.py builds a node tree from those tokens, and mako/codegen.py (the largest module at over 1,300 lines) walks that tree to emit Python source, which mako/pyparser.py and mako/_ast_util.py help validate and manipulate at the AST level. The generated source is then loaded as a real Python module and executed by mako/runtime.py, which supplies the Context, Namespace, and buffering machinery templates rely on at render time. mako/template.py is the user-facing facade tying compilation, module caching (via importlib.machinery/abc), and execution together, while mako/lookup.py manages resolving template files across search paths for inheritance and includes. This compile-then-execute separation is the defining architectural choice: it pushes cost to first-render/compile time and keeps the hot path a plain Python function call.

Tech Stack Mako targets modern CPython and PyPy (Python 3.10+ per pyproject.toml) with a single runtime dependency, MarkupSafe, used for safe HTML escaping in filters. The project builds with the standard setuptools backend and organizes development dependencies into explicit dependency-groups: tests (pytest, Beaker, dogpile.cache, Pygments, Babel, lingua, junitparser), coverage (pytest-cov), and lint (flake8 with import-order and docstring plugins, plus a pinned Black formatter). Optional extras wire in Babel- and lingua-based translation extraction and a Beaker-backed cache implementation, and the package registers entry points for Pygments lexers and TurboGears’s templating-engine plugin system, reflecting its role as embeddable infrastructure across several Python web stacks.

Code Quality The test/ directory contains around 30 dedicated test modules covering the lexer, parse tree, code generation, runtime, caching, inheritance, namespaces, decorators, loops, and the CLI (test_cmd.py), run through pytest with a pre-commit hook enforcing flake8 (including import-order and docstring checks) and Black formatting. Error handling is centralized in a purpose-built mako/exceptions.py with a MakoException/RuntimeException hierarchy and rich traceback formatting (RichTraceback) that maps runtime failures back to source template lines rather than raw Python tracebacks. There is no static type-checking configuration (no mypy group in pyproject.toml), so the codebase relies on tests and lint rather than type enforcement for correctness.

API Design Getting started requires only a couple of lines: construct a Template from text= or filename= and call .render(), or build a TemplateLookup when templates need to resolve each other across a directory tree for inheritance and includes. Class and function docstrings throughout mako/template.py and mako/runtime.py are written in full Sphinx-style prose with parameter descriptions, and the public surface (Template, TemplateLookup, Context) stays small and consistently named. The tradeoff is depth: templates that lean on <%def>, namespaces, and custom filters require understanding Mako’s own compilation model, which is a steeper step than a purely string-substitution templating library.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search