Create beautiful, flexible Application & Admin UIs in pure Ruby
Matestack UI ships styled UI components and smart CRUD tools for maximum productivity
How about putting together prebuilt styled components in pure Ruby rather than configuring something like ActiveAdmin? You can reuse existing security policies and unique business logic while rapidly implementing beautiful admin or application UIs!
Just like Matestack's core library matestack-ui-core
, the addon library matestack-ui
can be seamlessly integrated on top of existing controllers, models, routes and authentication/authorisation policies. Use solid UI abstraction while not compromising on the flexibility you need to drive your business!


Flexible, responsive, prebuilt app layouts
Use our prebuilt app templates through class inheritance in order to quickly setup typical layouts including sidebar and header navigation. Styles can be customized via SCSS theming.
Thanks to the fact that you're dealing with pure Ruby classes, it's also pretty easy to modify prebuilt UI structures and appearance in order to tailor the admin app to your individual needs.
app/matestack/my_admin/app.rb
class MyAdmin::App < Matestack::Ui::Apps::AdminTemplate
# the response method is defined by the parent class
# you just need to pass in some configuration using the methods below
# it's still possible to overwrite and adjust the response
# defined in the parent class
def sidebar_top_partial
div class: "text-center" do
transition path: root_path, delay: 300 do
heading size: 4, text: "Your Rails Backend"
end
end
div class: "text-center my-5" do
avatar img_path: asset_pack_url('media/images/avatar-placeholder.png')
div class: "my-3" do
plain current_admin.email
end
end
end
def sidebar_navigation_items
[
{ type: :transition, path: dummy_dashboard_path, text: "Dashboard", icon: "columns-gap" },
{ type: :transition, path: dummy_products_path, text: "Products", icon: "box" },
{ type: :transition, path: dummy_customers_path, text: "Customers", icon: "people-fill" },
{ type: :transition, path: dummy_orders_path, text: "Orders", icon: "cart-check-fill"},
]
end
def toasts
[
{ show_on: "failure", class: "bg-danger text-white", body: "Error!" },
{ show_on: "success", class: "bg-primary text-white", body: "Success!" },
]
end
end

Powerful page layout components for great UI experience
User components like `page_heading` or `section_card` together with grid components like `row` and `col` in order to quickly create a well structured, consistent and good looking UI.
Split rendering of complex, data-intesive UIs with Matestack's core `async` component and increase initial page load performance dramatically! All without writing one line of JavaScript.
app/matestack/my_admin/dashboard/show.rb
class MyAdmin::Pages::Dashboard::Show < Matestack::Ui::Page
def response
page_heading title: t("dashboard.title"), subtitle: t("dashboard.subtitle")
row do
col md: 6 do
analytics_partial
end
col md: 6 do
activity_partial
end
end
end
def analytics_partial
async defer: 300, id: "products-card" do
dashboard_products
end
async defer: 600, id: "revenue-card" do
dashboard_revenue
end
end
def activity_partial
row do
col do
async defer: 900, rerender_on: "activity-tracked", id: "activity-card" do
dashboard_activity
end
end
end
end
end
app/matestack/my_admin/components/dashboard/revenue.rb
# registered as `dashboard_revenue` via component registry
class MyAdmin::Components::Dashboard::Revenue < Matestack::Ui::Component
def response
section_card title: t("dashboard.revenue.title"), subtitle: t("dashboard.revenue.subtitle") do
row do
col xl: 6 do
text_kpis_partial
end
col xl: 6, class: "py-3" do
chart_kpis_partial
end
end
end
end
# ...
end

Chart.js components accessible in pure Ruby
Want to visualize some data in charts? Matestack UI integrates chart.js and allows you to use chart components in pure Ruby without thinking of the JavaScript side!
Choose from `line`, `doughnut`, `bar` or `pie` charts and use theme colors for consistent coloring of datasets without touching CSS.
app/matestack/my_admin/components/dashboard/revenue.rb
class MyAdmin::Components::Dashboard::Products < Matestack::Ui::Component
def response
section_card title: t("..."), subtitle: t("...") do
row do
col xl: 6 do
text_kpis_partial
end
col xl: 6, class: "py-3" do
chart_kpis_partial
end
end
end
end
protected
# ...
def chart_kpis_partial
chart type: :doughnut,
datasets: [
{
data: top_5_product_values,
backgroundColor: [:primary, :secondary, :blue, :indigo, :info]
},
],
labels: top_5_product_names
end
def top_5_products
OrderItem
.group(:product_id)
.sum(:price_in_euro)
.sort_by{|k, v| v}
.reverse
.first(5)
end
def top_5_product_values
top_5_products
.map { |product_id, value| value }
end
def top_5_product_names
top_5_products
.map { |product_id, value| Product.find(product_id).name }
end
end

Reactive forms in no time
Matestack's core library already ships reactive forms, used with pure Ruby. Within matestack-ui you get styled form component, enabling you to create beautiful, reactive forms with a few lines of Ruby!
Create styled forms, with reactive error/success rendering without thinking of any implementation detail!
app/matestack/my_admin/components/users_form.rb
class MyAdmin::Components::UsersForm < Matestack::Ui::Component
requires :user
def response
form form_config do
bootstrap_input key: :name, type: :text, label: "Name"
bootstrap_input key: :avatar, type: :file, label: "Avatar"
bootstrap_select key: :role, options: [:client, :admin], label: "Role",
placeholder: "Select Role"
bootstrap_switch key: :active, label: "Active?"
bootstrap_submit button_variant: :primary, spinner_variant: :light, text: "Submit"
end
end
def form_config
{
multipart: true, # due to file upload
for: user,
path: admin_user_path(user.id),
method: :put,
success: {
emit: :success
},
failure: {
emit: :failure
}
}
end
end

Reactive, paginated, filterable tables, without the JavaScript hussle
Implementing a paginated, filterable collection is exhausting. And what about a reactivity when switching through the pages in order to avoid full page reloads? You don't want to build that yourself! That's why we've created the `collection` component, shipped within matestack-ui-core. The `smart_collection` shipped with `matestack-ui` gives you even more:
A few lines of Ruby is enough to add a styled, reactive paginated table with filters to your UI! You can optionally modify column rendering and per-row actions via method injection.
app/matestack/my_admin/pages/orders/index.rb
class MyAdmin::Pages::Orders::Index < Matestack::Ui::Page
def response
# ...
section_card do
smart_collection collection_config
end
# ...
end
def collection_config
{
id: 'orders',
# Active Record query:
items: Order.includes(:customer, :order_items).all,
paginate: 10,
rerender_on: "success",
columns: {
# just render the ID:
id: 'ID',
# render an attribute of a child model:
'customer.last_name': {
# use a specific table column heading:
heading: 'Customer Name'
},
price_in_euro: {
heading: 'Price in €',
# transform the column content with a Proc:
format: -> (column_data){ "#{column_data} €" },
text: :right
}
},
filters: {
'customer.last_name': {
placeholder: 'Filter by Customer Name',
match: :starts_with,
}
},
slots: {
# inject a method which defines the per row actions:
table_item_actions: method(:table_item_actions)
}
}
end
def table_item_actions order
slot do
transition path: edit_dummy_order_path(order), delay: 300 do
btn outline: true, size: :sm, variant: :primary do
bootstrap_icon name: 'arrow-right', size: 20
end
end
end
end
end

Customized collection rendering, if tables are not enough
You like, what the `smart_collection` does, but want to render something different than a table? No worries: you can inject your very own method, rendering the collection items.
In this example we're using our own `collection_rendering` method in order to render cards in a grid rather than displaying a table. All other features of a `smart_collections` are still working.
app/matestack/my_admin/pages/products/index.rb
class MyAdmin::Pages::Products::Index < Matestack::Ui::Page
def response
# ...
section_card do
smart_collection collection_config
end
# ...
end
def collection_config
{
id: 'products',
items: Product.all,
paginate: 9,
rerender_on: "success",
filters: {
name: {
placeholder: 'Filter by Name',
match: :like
},
},
slots: {
collection_rendering: method(:collection_rendering)
}
}
end
def collection_rendering products
slot do
row do
products.each do |product|
col xl: 4, class: "mb-3" do
collection_card product
end
end
end
end
end
def collection_card product
card title: product.name, subtitle: "#{product.price_in_euro} €", class: "h-100" do
paragraph class: "fw-lighter", text: product.description
transition path: edit_dummy_product_path(product), delay: 300 do
btn outline: true, size: :sm, variant: :primary do
bootstrap_icon name: 'arrow-right', size: 20
end
end
action product_delete_action_config(product) do
btn outline: true, size: :sm, variant: :danger do
bootstrap_icon name: 'trash2', size: 20
end
end
end
end
def product_delete_action_config product
{
method: :delete,
path: dummy_product_path(id: product.id),
confirm: true,
success: {
emit: "success"
}
}
end
end

All Bootstrap v5 components, available in pure Ruby
Alongside smart components, `matestack-ui` ships all Bootstrap v5 components enabling you to use them in pure Ruby.
Imagine adding a Bootstrap `card` component within one line of Ruby, skipping recreating the required DOM structures again and again? Mix that with Matestack's core components, Bootstrap's utility classes or custom CSS for customized UI implementation. That means you're able to use Bootstrap and Matestack UI components with a high level of abstraction for maximum productivity right next to core components like `div` with a lower level of abstraction for maximum flexibility!
On top of that, you're able to use all kinds of methods in order to render your UI based on conditions like `current_user.is_super_admin?`. Adjusting the UI to your custom rules based on pure Ruby is super easy. That's what we call `flexible abstraction`!
app/matestack/my_admin/pages/customer/index.rb
class MyAdmin::Pages::Customer::Index < Matestack::Ui::Page
def response
container do
row do
Customer.last(6).each do |customer|
col sm: 4, class: "mt-3" do
card_for(customer)
end
end
end
end
end
def card_for customer
card title: customer.name, img_path: asset_pack_url('.../xyz.png'), class: "shadow-sm" do
card_body_for(customer)
end
end
def card_body_for customer
small class: "mb-3" do
b text: "Email:"
plain customer.email
end
if current_user.is_super_admin?
transition path: form_path(id: customer.id) do
btn size: :sm, text: "edit", class: "mt-3"
end
end
end
end

Progressive integration
Just like matestack-ui-core, easily integrate matestack-ui into existing Rails projects. Integrate bootstrap components step by step.

Flexible abstraction
Unlike other admin UI gems, you can use solid abstraction while still being able to implement and reuse your business logic without being bound to a configuration-only approach!

Tailor to your usecase
Besides styling customizations, you are completely free to integrate the components into your individual workflows, security polcies and data structures.
Matestack UI ships all you need to build beautiful, reactive UIs in pure Ruby and smart CRUD components. Don't think about styling anymore and just create admin or application UIs faster than ever before!
- Everything included in Matestack UI Core, plus:
- Admin and application UI templates in pure Ruby
- Admin and application UI components in pure Ruby
- Styled, reactive forms in pure Ruby
- Styled, reactive date/timepicker in pure Ruby
- Styled, reactive collections in pure Ruby
- Styled, reactive charts in pure Ruby
- All Bootstrap v5 components available in pure Ruby
- Growing library of additional components (Kanban Board, Devise Components...)
- Priorized Support via private Discord channel
You need a component which is not available yet? Matestack can be extended without limitation. I create the missing component for you on a discounted price, if I'm allowed to provide the new component to all Matestack users.
- Requirements engineering
- Component development
- Testing and documentation
- Deploy