Gems I use for Rails SaaS apps

Being a Ruby on Rails developer you are spoiled with great, mature libraries to add specific functionality to your app. Having built (successful) SaaS apps for more than a decade, I’ve built a small selection of gems I always add to my (SaaS) Rails apps and a few I reach for when specific features are needed.

When to use a gem or when to build?

This is highly personal, but a rule of thumb I use is that it needs to add functionality that works on the edges and doesn’t add pure business logic. Example: if a core feature of my app is direct messaging, I won’t use a gem for that, but I would use a gem for the sending (eg. SMS notifications) part. Other things that come into play: lindy-effect and if the maintainers are (longterm) invested in Ruby/Rails.

The following gems go into every SaaS app I built. I excluded gems that are added by default, like rails (🦉), bootsnap, or common ones like stripe and so on. Sometimes I build smaller (side-project) apps that have a different purpose—then I might choose other options.

Gems for every app

In alphabetical order:

action_policy

After having used Pundit for some time. I’ve found action_policy a more-versatile option for my authorization needs. Particularly like that I can choose another resource thancurrent_user to base my authorizations off—which is common for SaaS apps (team member, workspace, etc)

anyway_config

From the same author as action_policy. It allows me to set up configuration objects. It will then use the defined default value, Rails credentials or environment variables.

Example from my app:

# frozen_string_literal: true

class StripeConfig < ApplicationConfig
  attr_config :api_key, :signing_secret,
    :default_price_id, api_version: "2024-12-18.acacia", max_network_retries: 2
end

The api_key and signing_secret are read from the Rails Credentials, but if I need to change either one, because of a leak, without a deploy, I can set STRIPE_API_KEY=sk_1234.

Just having all configuration for services or other abstractions in one place really makes it easier.

good_job

Before good_job I used Sidekiq. And it is great. But the dependency on Redis is something I dont like. If you run a small SaaS (with a team of one), every dependency you can remove is a win. Good Job is great for that. I like it uses PostreSQL and you can “inline” yous jobs queue. This latter feature allowed me to grow a SaaS to ~1k in MRR on just one Heroku hobby dyno; I think that is amazing.

lograge

Not much to say about this one, just that it keeps logs in check in production. I add the gem and create an initializer like this:

Rails.application.configure do
  config.lograge.enabled = if !Rails.env.development? || ENV["LOGRAGE_IN_DEVELOPMENT"] == "true"
    true
  else
    false
  end

  config.lograge.custom_options = lambda do |event|
    options = event.payload.slice(:request_id, :user_id)

    options
  end
end

rails_designer

This one might not surprise you as Rails Designer’s UI Components Library was extracted from previous SaaS’. I use most of the available components, either as-is, sub-classed or tweaked slightly to match the app’s UI.

rails_icons

Every (SaaS) app needs icons. They help guide the user or help them navigate quicker. Rails Icons lets you easily add icons from many icon libraries. There is also support to add icon libraries that don’t have first-party support while using the same API. This gem is sponsored by Rails Designer.

stealth_dom_id

This maybe could’ve been a file in your lib-folder, but having it as a gem helps to spread the idea around better. If you use dom_id a lot, you might want to use this gem. It helps hide the record’s primary id, which might be business information you don’t want to share.

strong_migrations

Not gonna lie: database migrations in production with paying customers is not something that sparks joy for me. This gem takes away a tiny amount of stress, so I add it to every app.

Gems for specific features

Some features I don’t need in every app, but when I do, these gems are the ones I want.

alba

Alba is the gem I use when I need to serialize my JSON. Easy to get started, but packs enough features to be still versatile.

discard

For none of my SaaS’ do I keep data around for longer than needed, but fairly often do I need a feature like archive or trash user’s records. Discard does it right.

http.rb

If I need to make requests with Ruby, I reach for this gem. I like the API, feels more Ruby-like than Ruby’s own API.

positioning

From the same author as this gem, ranked-model, was my previous go-to gem for positioning records. I like the simple premise of positioning, while still matching all my ordering needs.

Published at . Last updated at . Have suggestions or improvements on this content? Do reach out.