Skip to main content

Avo (Rails) Review 2026: Ruby on Rails Admin Framework for SaaS

·StarterPick Team
avorailsrubyreview2026

TL;DR

Avo is Rails' answer to Django Admin — but dramatically more powerful. It auto-generates admin UI from your ActiveRecord models with filtering, search, custom actions, and dashboards. At $149-$399/year, it's a Rails SaaS component, not a full boilerplate. Combine Avo with a Rails SaaS foundation and you have one of the most productive admin panel setups available. Best for Rails teams who appreciate convention over configuration.

What Avo Is

Avo is a Rails engine (gem) that adds a powerful admin panel to any Rails app:

# Gemfile
gem 'avo'

# config/initializers/avo.rb
Avo.configure do |config|
  config.root_path = '/avo'
  config.authenticate_with do
    warden.authenticate! scope: :user
  end
  config.current_user_method(:current_user)
  config.authorization_client_class = "AvoAuthorization"
end

Resource-Based Architecture

Avo resources map to ActiveRecord models:

# app/avo/resources/user_resource.rb
class UserResource < Avo::BaseResource
  self.title = :email
  self.search_query = -> {
    scope.ransack(email_cont: params[:q], name_cont: params[:q], m: 'or').result
  }

  field :id, as: :id
  field :name, as: :text
  field :email, as: :email
  field :created_at, as: :date_time, sortable: true
  field :subscription_status,
    as: :select,
    options: { active: 'Active', inactive: 'Inactive', trialing: 'Trialing' }

  # Computed field
  field :mrr, as: :money, currency: :usd, only_on: [:show, :index] do
    record.subscription&.monthly_revenue || 0
  end

  filter Avo::Filters::SelectFilter, name: 'subscription_status'

  action Avo::Actions::SendWelcomeEmail
  action Avo::Actions::CancelSubscription
end

This generates a fully functional admin UI: list view with search/filter, detail view, create/edit forms.


Custom Actions

# app/avo/actions/cancel_subscription.rb
class Avo::Actions::CancelSubscription < Avo::BaseAction
  self.name = 'Cancel Subscription'
  self.confirm_button_label = 'Yes, cancel'
  self.destructive = true

  field :reason, as: :textarea, placeholder: 'Cancellation reason'

  def handle(query:, fields:, current_user:, resource:)
    query.each do |user|
      if user.subscription&.active?
        user.subscription.cancel!(
          reason: fields[:reason],
          canceled_by: current_user.email
        )

        # Log audit trail
        AuditLog.create!(
          actor: current_user,
          target: user,
          action: 'subscription.canceled',
          metadata: { reason: fields[:reason] }
        )
      end
    end

    succeed 'Subscriptions canceled successfully.'
  end
end

Dashboard and Metrics

# app/avo/dashboards/main_dashboard.rb
class MainDashboard < Avo::Dashboards::BaseDashboard
  self.id = 'main'
  self.name = 'Overview'

  card Avo::Cards::MrrCard
  card Avo::Cards::ActiveSubscribersCard
  card Avo::Cards::ChurnRateCard
  card Avo::Cards::RevenueChartCard, cols: 2
end

# A metric card
class Avo::Cards::MrrCard < Avo::Dashboards::MetricCard
  self.name = 'Monthly Recurring Revenue'
  self.prefix = '$'
  self.refresh_every = 5.minutes

  def value
    Subscription.active.sum(:monthly_revenue) / 100.0
  end

  def previous_value
    # MRR from same time last month for trend comparison
    Subscription.where(
      "created_at <= ?", 1.month.ago
    ).active_at(1.month.ago).sum(:monthly_revenue) / 100.0
  end
end

Avo in a Rails SaaS Stack

A typical Rails SaaS setup with Avo:

Rails 7.1
├── Authentication: Devise + OmniAuth
├── Billing: pay gem (Stripe wrapper)
├── Admin: Avo
├── Background Jobs: Sidekiq
├── Email: ActionMailer + Postmark
├── Database: PostgreSQL + ActiveRecord
├── Frontend: Hotwire (Turbo + Stimulus) or React/Inertia.js
└── Deployment: Render, Fly.io, or Heroku

The pay gem provides Stripe integration that integrates cleanly with Avo:

# With the pay gem
class User < ApplicationRecord
  pay_customer default_payment_processor: :stripe

  def active_subscriber?
    pay_subscriptions.active.exists?
  end
end

Rails vs Node.js for SaaS in 2026

FactorRails + AvoNext.js + Makerkit
Admin panelAvo (best in class)Makerkit admin (good)
ConventionVery highModerate
Type safetyRuby types (Sorbet optional)TypeScript
PerformanceExcellentExcellent
HiringRails devs (smaller pool)JS devs (large pool)
DeploymentServer requiredVercel/serverless
Background jobsSidekiq (battle-tested)Inngest/BullMQ
i18nBuilt-in Rails i18nExternal gems/packages

Rails' secret weapon: convention. A Rails senior developer can navigate any Rails app. There's no "which state manager did they choose?" — it's always whatever the Rails convention is.


Limitations

  • Avo cost: $149-399/year subscription model
  • Rails niche: Smaller 2026 ecosystem vs JavaScript
  • Serverless: Rails requires persistent server (no Vercel-style serverless)
  • Not a complete SaaS boilerplate: Avo is a component, not a full starter

Who Should Use Avo + Rails

Good fit:

  • Existing Rails shops building SaaS
  • Teams that need a best-in-class admin panel
  • SaaS products where the admin UI is complex (many custom actions, dashboards)
  • Founders with Ruby/Rails backgrounds

Bad fit:

  • New projects choosing a stack (Node.js ecosystem is larger)
  • Teams needing serverless deployment
  • Products where TypeScript end-to-end type safety is a priority

Final Verdict

Rating: 4/5 for Rails SaaS

Avo is the best admin framework in the Rails ecosystem — arguably the best in any ecosystem for convention-over-configuration admin UIs. Combined with a solid Rails SaaS foundation (Devise, pay gem, Sidekiq), it enables remarkably fast admin panel development. The trade-off is the annual cost and Rails' smaller 2026 ecosystem vs JavaScript alternatives.


Compare Rails and other backend framework boilerplates on StarterPick.

Check out this boilerplate

View Avo (Rails) on StarterPick →

Comments