Status
Accepted
Context
Slug requires a server-side templating mechanism to support its web framework and general text / HTML rendering needs.
The design goals for Slug strongly emphasize:
- explicit over implicit behavior
- simple over clever abstractions
- separation of concerns between logic and presentation
- predictable, testable execution
- ease of reimplementation in Slug itself (not just via FFI)
Historically, many templating systems have blurred the line between presentation and computation, embedding control flow, expressions, and side effects directly into templates. This often leads to:
- duplicated business logic
- hidden execution paths
- difficult-to-reason-about rendering behavior
- security and maintainability issues over time
Slug explicitly rejects this direction.
A templating system for Slug must therefore:
- avoid becoming a second programming language
- keep all logic in Slug code
- be small enough to implement natively and test rigorously
- support partial and fragment-based rendering
- behave deterministically with respect to whitespace and output
Decision
Slug adopts Mustache as its first and canonical templating engine.
1. Logic-less by Design
Mustache templates are intentionally logic-less:
- no conditionals
- no loops
- no expressions
- no assignments
All computation happens in Slug. Templates receive fully-prepared data and render it declaratively.
This aligns directly with Slug’s philosophy:
Templates describe what to render; Slug decides why.
2. Strong Separation of Concerns
Under this model:
- Slug code handles control flow, branching, iteration, and data shaping
- Templates perform only interpolation and structural expansion
This separation:
- reduces cognitive load when reading templates
- eliminates hidden execution paths
- avoids template-specific debugging tools or mental models
3. Deterministic, Fragment-Oriented Rendering
Slug favors server-side rendering of small, composable output fragments.
Mustache naturally supports:
- partial templates
- fragment reuse
- deterministic output
- aggressive caching of parsed templates
This makes it suitable as a foundational rendering mechanism without requiring client-side execution or runtime evaluation within templates.
4. Small, Well-Defined Specification
Mustache has:
- a compact, language-agnostic specification
- extensive cross-language test suites
- well-understood edge cases (notably whitespace handling)
This enables:
- a fully native Slug implementation
- spec-driven development and verification
- long-term maintainability without external dependencies
The effort to pass the official Mustache specification suite validated that the behavior is:
- precisely defined
- testable
- stable across implementations
5. Security and Predictability
Because Mustache does not allow arbitrary code execution:
- templates cannot perform side effects
- HTML escaping is the default behavior
- template injection risks are significantly reduced
This supports Slug’s goal of making the “safe path” the default path.
6. Future Extensibility Without Lock-In
Adopting Mustache does not preclude future templating options.
This decision establishes:
- a baseline templating model
- a clear contract between Slug code and views
- a reference implementation for how templating integrates with the runtime
Additional templating engines may be explored later, but Mustache defines the minimum acceptable standard for simplicity and clarity.
Consequences
Positive
- Clear and enforceable separation between logic and presentation
- Native implementation is feasible and already underway
- Deterministic, spec-backed rendering behavior
- Easy to cache, test, and reason about
- Avoids “template as a second language” syndrome
Negative
- Templates cannot express conditional logic directly
- Data must be shaped explicitly in Slug before rendering
- Some developers may initially find this restrictive
These constraints are intentional and aligned with Slug’s design philosophy.
Neutral
- Mustache whitespace rules are subtle and require careful implementation
- Some advanced Mustache features (e.g., inheritance) may be deferred or omitted
- This ADR does not mandate Mustache as the only templating system forever, only the first and canonical one
Summary
Mustache was chosen not because it is powerful, but because it is deliberately limited.
Those limits reinforce Slug’s core values:
- clarity
- explicitness
- simplicity
- correctness
As a result, Mustache provides a stable, predictable foundation for Slug’s templating needs without compromising the language’s design integrity.