ViewComponent

ViewComponent Installation

Install components using GitHub's ViewComponent library for encapsulated, testable UI.

Overview

ViewComponent is a framework for building reusable, testable, and encapsulated view components in Ruby on Rails. Components are Ruby classes with associated templates, providing better organization and type safety.

Best for: Teams who want typed interfaces, better testability, and a more structured approach to UI components.

Benefits

  • Encapsulation — Logic and presentation in one place
  • Testability — Unit test components in isolation
  • Type safety — Define explicit interfaces with typed parameters
  • Performance — Built-in template caching and precompilation

Setup

If you haven't already, add the ViewComponent gem to your application:

Gemfile
gem "view_component"

Then install the gem:

Terminal
bundle install

ViewComponent works out of the box with Rails 6.1+. For additional configuration options, see the official documentation.

Project Structure

ViewComponent components live in app/components/:

Directory Structure
app/
├── components/
│   ├── dropdown_component.rb       # Ruby class
│   ├── dropdown_component.html.erb # Template
│   ├── modal_component.rb
│   ├── modal_component.html.erb
│   └── ...
└── javascript/
    └── controllers/
        ├── dropdown_controller.js  # Stimulus controller
        ├── modal_controller.js
        └── ...

Each component consists of a Ruby class (defining the interface) and an ERB template (the HTML structure). Stimulus controllers are still used for JavaScript interactivity.

Installing Components

1

Create the components directory

Terminal
mkdir -p app/components
2

Copy the Ruby class

From the component page, copy the _component.rb file to app/components/component_name_component.rb.

3

Copy the template

Copy the .html.erb template to app/components/component_name_component.html.erb.

4

Copy the Stimulus controller

If the component has JavaScript behavior, copy the controller to app/javascript/controllers/.

Usage Example

Render ViewComponents using the render helper with a component instance:

app/views/layouts/application.html.erb
<%# Render the dropdown component %>
<%= render DropdownComponent.new(
    label: "Options",
    items: [
      { label: "Edit", href: edit_path(@item) },
      { label: "Delete", href: @item, method: :delete }
    ]
) %>

With Slots

Some components use ViewComponent slots for flexible content composition:

Using slots
<%= render ModalComponent.new(title: "Confirm Action") do |modal| %>
  <% modal.with_body do %>
    <p>Are you sure you want to proceed?</p>
  <% end %>

  <% modal.with_footer do %>
    <button class="btn-secondary">Cancel</button>
    <button class="btn-primary">Confirm</button>
  <% end %>
<% end %>

Check each component's documentation for the available parameters and slot options.