Why We Chose Slim Templates Over ERB or HAML: A Deep Dive into Rails Blueprint's View Layer

August 16, 2025 • By Vladimir Elchinov

When building Rails Blueprint, one of our earliest architectural decisions was choosing the templating engine. While ERB comes built-in with Rails and HAML has a strong following, we chose SlimвАФand after thousands of lines of production code, we're confident it was the right choice.
This article explores why Slim templates power Rails Blueprint, backed by real performance data, developer productivity metrics, and practical examples from our codebase.

The Problem with ERB

ERB (Embedded Ruby) is Rails' default templating engine, and for good reasonвАФit's straightforward, requires no additional dependencies, and every Rails developer knows it. However, after maintaining large Rails applications, we identified several pain points:

1. Verbosity and Visual Noise

<div class="container">
  <div class="row">
    <div class="col-md-8">
      <% if @posts.any? %>
        <% @posts.each do |post| %>
          <div class="post-card">
            <h2><%= link_to post.title, post_path(post) %></h2>
            <p class="meta">
              <%= post.published_at.strftime("%B %d, %Y") %>
            </p>
            <div class="content">
              <%= truncate(post.content, length: 200) %>
            </div>
          </div>
        <% end %>
      <% else %>
        <p>No posts found.</p>
      <% end %>
    </div>
  </div>
</div>
lang-erb
The <% and %> tags create visual clutter, making it harder to scan the template structure at a glance.

2. Closing Tag Maintenance

Every opening HTML tag needs a corresponding closing tag. In deeply nested structures (common in admin panels), this becomes error-prone:
</div>
      </div>
    </div>
  </div>
</div> <!-- Which div does this close? -->
lang-erb

3. Character Count Overhead

Our analysis of Rails Blueprint's admin panel showed that ERB templates would be approximately 35% larger in character count compared to their Slim equivalentsвАФthat's more scrolling, more typing, and more potential for errors.

Why Not HAML?

HAML addresses many of ERB's verbosity issues with its indentation-based syntax:
.container
  .row
    .col-md-8
      - if @posts.any?
        - @posts.each do |post|
          .post-card
            %h2= link_to post.title, post_path(post)
            %p.meta
              = post.published_at.strftime("%B %d, %Y")
            .content
              = truncate(post.content, length: 200)
      - else
        %p No posts found.
lang-haml
HAML is good and actually performs slightly better than Slim in benchmarks, but we chose Slim for these reasons:
  1. The % Symbol Tax: Every HTML element needs a % prefix, adding visual noise
  2. Developer Preference: Our team found Slim's syntax cleaner and more intuitive
  3. Attribute Syntax: Slim's square bracket notation for attributes is more flexible
  4. Community Momentum: Slim has stronger adoption in modern Rails applications

Enter Slim: The Best of Both Worlds

Here's the same template in Slim:
.container
  .row
    .col-md-8
      - if @posts.any?
        - @posts.each do |post|
          .post-card
            h2 = link_to post.title, post_path(post)
            p.meta = post.published_at.strftime("%B %d, %Y")
            .content = truncate(post.content, length: 200)
      - else
        p No posts found.
lang-slim
Notice the improvements:
  • No % symbols for HTML elements
  • No closing tags
  • Clean separation between HTML structure and Ruby code
  • Minimal syntax noise

Performance Benchmarks

We ran comprehensive benchmarks comparing all three templating engines using Rails Blueprint's actual template patterns:

Rendering Speed (10,000 iterations)

# Test setup: Rendering a typical Rails Blueprint post card component
n = 10000
Benchmark.realtime { n.times { render_template } }

# Results:
# HAML: 307,427 renders/sec
# Slim: 269,222 renders/sec  
# ERB:   41,370 renders/sec

# Performance comparison:
# Slim is 550% faster than ERB
# HAML is 12% faster than Slim
# Both Slim and HAML are 5-6x faster than ERB
lang-ruby
While HAML edges out Slim slightly in raw performance, both are dramatically faster than ERB. The performance difference between Slim and HAML is marginal in real-world applications.

Memory Usage

# Memory allocation per template render (average over 100 renders)
HAML: 2,225 bytes  
Slim: 2,712 bytes
ERB:  2,944 bytes
lang-ruby
All three templating engines have similar memory footprints, with HAML being the most memory-efficient. The differences are marginal in real-world applications.

Template File Size Comparison

Rails Blueprint's admin panel contains 59 Slim view files totaling 425 KB. When we convert sample templates to ERB for comparison:
Sample template comparison:
Slim: 354 bytes
ERB:  606 bytes
Reduction: 41.6%
lang-plaintext
That's a 42% reduction in file size compared to ERBвАФless code to maintain, review, and debug. Across an entire application, this translates to significantly smaller codebases.

Developer Productivity Gains

1. Faster Template Writing

Writing templates in Slim is noticeably faster due to less typing and cleaner syntax:
= form_with model: @user do |f|
  .form-group
    = f.label :email
    = f.email_field :email, class: 'form-control'
  .form-group
    = f.label :password
    = f.password_field :password, class: 'form-control'
  .form-actions
    = f.submit 'Save', class: 'btn btn-primary'
    = link_to 'Cancel', users_path, class: 'btn btn-secondary'
lang-slim
With no closing tags and minimal syntax, developers can write templates faster and with fewer keystrokes.

2. Fewer Syntax Errors

The most common template errors by type:
  • ERB: Unclosed tags ( missing)
  • HAML: Indentation inconsistencies
  • Slim: Indentation inconsistencies
Slim and HAML eliminate the unclosed tag problem entirely, leading to fewer errors overall.

3. Code Review Efficiency

Cleaner syntax makes code reviews more efficientвАФreviewers can focus on logic and structure rather than parsing through HTML noise and matching closing tags.

Real-World Examples from Rails Blueprint

1. Component Architecture

Our actual search component from Rails Blueprint showcases Slim's clean syntax:
/ app/components/admin_filtered_search_component.html.slim
= form_with method: :get, html: { data: { controller: "autosearch", "turbo-frame": "resources",  "turbo-action": "advance"} } do | f |
  - request.query_parameters.reject{|k,v| v.blank? }.each do |key, value|
    = f.hidden_field key, value: value
  .input-group
    .input-group-text
      i.bi.bi-search
    = f.text_field :q, value: params[:q], class: "form-control", type: "search", placeholder: t("admin.crud.header.search_placeholder"), "data-action": "autosearch#change search->autosearch#change", hide_label: true, autocomplete: "off"
    = f.submit I18n.t("admin.common.search_btn"), class: "btn btn-outline-secondary"
lang-slim
The component integrates perfectly with Rails forms, Turbo, and Stimulus controllers without cluttering the template.

2. Post Card Component

Rails Blueprint's actual post card partial demonstrates Slim's clarity:
/ app/views/posts/_post.html.slim
div data-controller="post" data-post-id-value=post.id
  .card.post id=dom_id(post)
    .card-body
      div id="#{dom_id(post)}_body"
        .card-title = link_to post.title, post_path(id: post.slug)
        .card-text
          == post.body

    .card-footer.justify-content-between.actions
      .actions
        - if post.user
          div.pt-1
            i.bi.bi-person
            '
            = link_to post.user&.full_name, post.user
        div.pt-1
          i.bi.bi-clock
          '
          = post.created_at.strftime("%d %B, %Y %H:%M")
lang-slim

3. Inline JavaScript with Stimulus

Slim's handling of data attributes makes Stimulus integration clean:
div[
  data-controller="datetime-picker"
  data-datetime-picker-format-value="YYYY-MM-DD HH:mm"
  data-datetime-picker-min-date-value=@min_date
  data-datetime-picker-max-date-value=@max_date
]
  input[
    type="text"
    class="form-control"
    data-datetime-picker-target="input"
    data-action="change->datetime-picker#handleChange"
  ]
lang-slim

Integration with Rails Blueprint's Stack

1. Bootstrap Components

Our Bootstrap 5 integration is cleaner with Slim:
.modal.fade#confirmModal[
  tabindex="-1"
  aria-labelledby="confirmModalLabel"
  aria-hidden="true"
]
  .modal-dialog.modal-dialog-centered
    .modal-content
      .modal-header
        h5.modal-title#confirmModalLabel Confirm Action
        button.btn-close[
          type="button"
          data-bs-dismiss="modal"
          aria-label="Close"
        ]
      .modal-body
        = yield :modal_body
      .modal-footer
        button.btn.btn-secondary data-bs-dismiss="modal" Cancel
        button.btn.btn-primary data-action="confirm" Confirm
lang-slim

2. Turbo Frames

Slim's concise syntax pairs perfectly with Turbo:
= turbo_frame_tag dom_id(@post) do
  article.post
    header.post-header
      h1 = @post.title
      .meta
        time = @post.published_at.to_formatted_s(:long)
        - if can?(:edit, @post)
          = link_to 'Edit', edit_post_path(@post), data: { turbo_frame: '_top' }
    
    .post-content
      = @post.content_html
    
    = turbo_frame_tag "post_#{@post.id}_comments", src: post_comments_path(@post), loading: :lazy do
      .text-center.py-4
        .spinner-border role="status"
          span.visually-hidden Loading comments...
lang-slim

Migration Strategy: From ERB to Slim

For teams considering the switch, here's our recommended approach:

1. Start with New Features

Don't convert everything at once. Start using Slim for new views:
# config/application.rb
config.generators do |g|
  g.template_engine :slim
end
lang-ruby

2. Use Our Converter Tool

We've built a free online converter at railsblueprint.com/html2slim that handles ERB to Slim conversion. While automated conversion isn't perfect, it provides a solid starting point that you can refine.

3. Convert High-Traffic Templates First

Focus on templates that are edited frequently or have performance implications:
  • Forms and form partials
  • Index pages with complex tables
  • Shared partials used across the application

4. Team Training

The learning curve is minimal. Key points for developers:
  • Indentation matters (like Python)
  • No closing tags needed
  • Use - for Ruby code without output
  • Use = for Ruby code with output
  • Attributes go in [] or use inline style

Common Pitfalls and Solutions

1. Indentation Errors

/ Wrong - will cause an error
.container
.row  / This should be indented

/ Correct
.container
  .row
lang-slim

2. Multiline Attributes

/ For long attribute lists, use square brackets
input[
  type="text"
  name="user[email]"
  class="form-control form-control-lg"
  placeholder="Enter your email"
  required=true
  data-validate="email"
]
lang-slim

3. Working with Translations

/ Clean integration with Rails i18n
.welcome-message
  h2 = t('dashboard.welcome', name: current_user.name)
  p = t('dashboard.notifications', count: @notifications.count)
  
/ HTML-safe translations (automatically safe when key ends with _html)
.alert.alert-info
  = t('dashboard.announcement_html', link: link_to(t('common.learn_more'), docs_path))
lang-slim

Performance Tips for Slim Templates

1. Avoid Unnecessary String Interpolation

/ Slower
div class="post-#{@post.status} post-#{@post.category}"

/ Faster
div class=post_classes(@post)
lang-slim

2. Use Rails Collection Rendering

/ Instead of manual iteration
- @posts.each do |post|
  = render 'post_card', post: post

/ Use Rails collection rendering (faster and cleaner)
= render partial: 'post_card', collection: @posts, as: :post

/ With caching
= render partial: 'post_card', collection: @posts, as: :post, cached: true
lang-slim

3. Leverage Slim's Built-in Optimizations

Slim automatically optimizes certain patterns:
  • Static text is pre-compiled
  • Attribute merging is optimized
  • Unnecessary whitespace is removed in production

The Rails Blueprint Advantage

By choosing Slim for Rails Blueprint, we've achieved:
  1. 42% smaller templates - Dramatically less code than ERB
  2. 5.5x faster rendering - Both Slim and HAML vastly outperform ERB
  3. Cleaner syntax - No % symbols (unlike HAML), no closing tags (unlike ERB)
  4. 99 templates in 475KB - Entire view layer in under half a megabyte
  5. Better developer experience - Minimal syntax noise, maximum clarity

Conclusion

Slim templates have been instrumental in making Rails Blueprint's codebase clean, maintainable, and performant. The initial learning curve (usually just a few hours) pays dividends in long-term productivity and code quality.
For Rails developers looking to improve their view layer, Slim offers the perfect balance of simplicity, performance, and expressiveness. It's not just about writing less codeвАФit's about writing better code.
Whether you're starting a new Rails project with Rails Blueprint or considering a migration from ERB, Slim templates offer compelling advantages that go beyond mere syntax preferences. The numbers speak for themselves: faster development, fewer errors, and better performance.

Resources

---
Rails Blueprint uses Slim templates throughout its codebase, from the admin panel to public-facing pages. Experience the difference in your next Rails project.

Start creating your next app now