DEV Community

Germán Alberto Gimenez Silva
Germán Alberto Gimenez Silva

Posted on • Originally published at rubystacknews.com on

✅ Building Clean and Reusable UI with ViewComponent in Rails

May 20, 2025

As Rails applications grow in size and complexity, maintaining views can become challenging. Traditional partials and helpers often lead to scattered logic, reduced testability, and hard-to-maintain code. This is where ViewComponent—a gem developed by GitHub—comes in to bring structure and object-oriented design to your views.


🚀 Need help with your Ruby on Rails project? Let’s get in touch


🚀 What is ViewComponent?

ViewComponent is a framework for creating reusable, testable, and encapsulated view components in Ruby on Rails. It encourages writing views as Ruby objects with templates, separating presentation logic from controllers and views.

Instead of this:


<%= render "shared/alert", type: "warning", message: "Be careful!" %>

Enter fullscreen mode Exit fullscreen mode

You write:


<%= render(AlertComponent.new(type: "warning")) do %>
  Be careful!
<% end %>

Enter fullscreen mode Exit fullscreen mode

🧱 Component Structure

Article content

A ViewComponent typically consists of two files:

  1. A Ruby class for logic: app/components/alert_component.rb
  2. An HTML/ERB template : app/components/alert_component.html.erb

✅ Example: Alert Component

Let’s create a simple AlertComponent.

app/components/alert_component.rb


class AlertComponent < ViewComponent::Base
  def initialize(type:)
    @type = type
  end
end

Enter fullscreen mode Exit fullscreen mode

app/components/alert_component.html.erb


<div class="alert alert-<%= @type %>">
  <%= content %>
</div>

Enter fullscreen mode Exit fullscreen mode

Usage in a view


<%= render(AlertComponent.new(type: "success")) do %>
  Your changes have been saved successfully!
<% end %>

Enter fullscreen mode Exit fullscreen mode

This renders:


<%= render(AlertComponent.new(type: "success")) do %>
  Your changes have been saved successfully!
<% end %>

Enter fullscreen mode Exit fullscreen mode

🔍 Benefits of Using ViewComponent

  • Encapsulation : Keeps logic and markup together.
  • Reusability : Components can be used across multiple views or even gems.
  • Testability : Easily test components in isolation.
  • Performance : Uses compiled templates and avoids repeated partial parsing.
  • Design System Friendly : Perfect for building reusable UI systems.

🧪 Testing Components

You can use RSpec or Minitest to write tests for components.


# spec/components/alert_component_spec.rb
require "rails_helper"

RSpec.describe AlertComponent, type: :component do
  it "renders the alert message" do
    render_inline(AlertComponent.new(type: "danger")) { "This is dangerous!" }

    expect(rendered_content).to include("alert-danger")
    expect(rendered_content).to include("This is dangerous!")
  end
end

Enter fullscreen mode Exit fullscreen mode

🎨 Advanced: Slots

Slots allow you to define named content areas.


class CardComponent < ViewComponent::Base
  renders_one :header
  renders_one :footer
end



<%= render(CardComponent.new) do |c| %>
  <% c.header { "Title" } %>
  This is the card content.
  <% c.footer { "Footer info" } %>
<% end %>

Enter fullscreen mode Exit fullscreen mode

🛠 Setup in Rails

To install:


bundle add view_component

Enter fullscreen mode Exit fullscreen mode

Then add to config/application.rb:


config.view_component.generate_sidecar = true

Enter fullscreen mode Exit fullscreen mode

Or run:


rails generate component Alert type

Enter fullscreen mode Exit fullscreen mode

📦 Great for Design Systems

If you’re working on a design system, ViewComponent is a powerful ally. It encourages small, focused components that follow the single-responsibility principle and can be styled consistently.

📚 Conclusion

ViewComponent offers a modern, component-based approach to building Rails views. It’s ideal for teams looking for better structure, testability, and maintainability in their front-end code.

Article content

Top comments (0)