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
| Factor | Rails + Avo | Next.js + Makerkit |
|---|---|---|
| Admin panel | Avo (best in class) | Makerkit admin (good) |
| Convention | Very high | Moderate |
| Type safety | Ruby types (Sorbet optional) | TypeScript |
| Performance | Excellent | Excellent |
| Hiring | Rails devs (smaller pool) | JS devs (large pool) |
| Deployment | Server required | Vercel/serverless |
| Background jobs | Sidekiq (battle-tested) | Inngest/BullMQ |
| i18n | Built-in Rails i18n | External 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.
Top comments (0)