# A Ruby Ecosystem for Web Apps

**URL:** <https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307>\
**Category:** general\
**Created:** [September 26, 2025, 11:23am UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307 "2025-09-26T11:23:01Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![moonglum](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/moonglum/32/968_2.png) [@moonglum](https://discourse.hanakai.org/u/moonglum)\
**Post date:** [September 26, 2025, 11:23am UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/1 "2025-09-26T11:23:01Z")

</div>

I’m currently looking into Hanami as an alternative to Rails 🙂 One big advantage Rails has over a lot of solutions (not just in the Ruby world, but in general) is the ecosystem of libraries around it. I think this is hard to replicate. So my thought was: What if the ecosystem wasn’t “Hanami” but “Rails/Rack applications” instead? This would allow the smaller Ruby frameworks like Hanami, Brut and Yippee to join forces instead of implementing the same functionality multiple times. Rails has a longer history of “sherlocking” popular solutions over the years (for example, Active Storage & Solid Queue) which drained a lot of energy out of the original projects. I propose to not follow that pattern, and instead of putting everything in the box, offer recipes to integrate solutions.

**The Core of Hanami**

In my humble opinion, the core of Hanami would be: Code Loading, Routing, Controllers, Views, Form Handling, Caching, integration with an asset pipeline and the model layer. The model layer is a bit more complicated, but I would like to leave this out of this discussion. The one thing I see missing here is internationalization, as it is closely integrated with the view layer. [There is a discussion about it here](https://discourse.hanakai.org/t/implementing-localization-with-i18n-gem/973).

**Authentication**

I think authentication is an excellent example. @timriley wrote a great post on how to use Rodauth with Hanami ([Discussion](https://discourse.hanakai.org/t/rodauth-hanami/1301)). For me, Rodauth would definitely be the first thing to try when setting up a Hanami app.

**Authorization**

For Authorization, I think Pundit and CanCanCan should both just work 🤔

**Jobs (Background Processing, Recurring Jobs)**

Sidekiq is definitely a solid choice in this area, and I assume it will just work with Hanami. For people that want to store their jobs in the database, I’m not sure if there is a good option:

- SolidQueue and GoodJob are both bound to ActiveJob/Rails
- Que could be an option (for PostgreSQL only) and looks maintained

So I would probably go with either Sidekiq or Que here.

**File Uploads**

Looking at the [solutions at Ruby Toolbox](https://www.ruby-toolbox.com/categories/rails_file_uploads):

- carrierwave still seems to be maintained - it is slightly bound to Rails, but might work?
  - refile was an attempt by the same team to “do it better this time”, but the last commit is over 5 years ago.

- paperclip [is deprecated](https://thoughtbot.com/blog/closing-the-trombone)
- shrine is really independent of the framework. But activity on it seems to have gone down quite a lot.
- The others all seem to be dead

So I’m not sure what I would go with here.

**Mails**

Not sure. The mail gem is at the core of ActionMailer, but I think it is quite attractive to have a solution that can also work with transactional email providers, as this is what I commonly use in production. Anyone got any ideas here?

**Deployment**

Both a classic setup with Capistrano and something like Ansible or a PaaS solution would work. For people who want a Container-based solution, kamal would work as well, but I’m not sure how many want to use a solution from 37signals 😉

**Logging & Instrumentation**

Structured logging would be quite good. semantic\_logger should work. For further instrumentation, I’m not sure. I would also be interested to see how well rack-mini-profiler works. I regularly use it in Rails app, and think it is quite helpful.

**Testing**

Both Minitest and RSpec will work with Hanami.

---

<div class="post-metadata">

**Author:** ![cllns](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/cllns/32/750_2.png) [@cllns](https://discourse.hanakai.org/u/cllns)\
**Post date:** [September 26, 2025, 4:06pm UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/2 "2025-09-26T16:06:46Z")

</div>

In short, **YES**. You see the vision. Welcome! 🌸 🌞

Every part of Hanami is modular, both in terms of letting you swap things _out_ of the full-stack framework, while letting users use libraries from Hanami that they like.

[Tim gave a talk](https://www.youtube.com/watch?v=6jUEmcezkBo&t=1963s) that touched on this, where he highlighted Roda, Phlex, and Shrine as Ruby gems that can be used across the ecosystem. I have some ideas about how to make this easier in Hanami by letting users easily create custom generators.

As for Brut and Yippee specifically, they both have different angles and visions of how they want to make Ruby web apps. This is good! They’re welcome to use any piece of Hanami that they’d like, but it’s also fine that they haven’t yet. We’ll support them if they do, and also. most importantly, support users who mix-and-match. (Specifically the forthcoming SQlite-only DB layer that will be part of Yippee is of great interest to me personally.)

Additionally, we want to support Rails libraries as well. In the spirit of welcoming _all_ Ruby uses, and also specifically to provide a path for people who want to migrate from Rails incrementally.

Thanks for articulating this!

---

<div class="post-metadata">

**Author:** ![moonglum](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/moonglum/32/968_2.png) [@moonglum](https://discourse.hanakai.org/u/moonglum)\
**Post date:** [September 26, 2025, 7:17pm UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/3 "2025-09-26T19:17:12Z")

</div>

Thanks a lot! And thanks for the warm welcome ❤

I just watched this brilliant talk, and it gives me a lot of positive energy 😍

---

<div class="post-metadata">

**Author:** ![tcannonfodder](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/tcannonfodder/32/969_2.png) [@tcannonfodder](https://discourse.hanakai.org/u/tcannonfodder)\
**Post date:** [September 27, 2025, 12:34pm UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/4 "2025-09-27T12:34:08Z")

</div>

IMO Shrine is still a gold-standard for file uploads; and the slower commits/activity don’t necessarily bother me when working on my own projects. It’s remarkably stable, versatile, and slots in nicely in a bunch of places.

(Not saying you were trying to dismiss shrine, just wanted to say that it still works great! 😄)

---

<div class="post-metadata">

**Author:** ![wout](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/wout/32/684_2.png) [@wout](https://discourse.hanakai.org/u/wout)\
**Post date:** [September 27, 2025, 1:13pm UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/5 "2025-09-27T13:13:45Z")

</div>

> [@tcannonfodder](#):
>
> IMO Shrine is still a gold-standard for file uploads;

I was about to say the same thing. Shrine is stable, feature-complete, and framework-agnostic.

> [@moonglum](#):
>
> Que could be an option (for PostgreSQL only) and looks maintained

Thanks for this! I didn’t know Que. Not having Redis as a dependency is definitely a plus.

For **Deployment** , [Caprover](https://caprover.com/) has treated me well. I’ve been using it in production for four years now on five different servers with dozens of apps, and it’s very reliable. Deployment can go either direct to the server, though GH Actions, or any other CI/CD flow.

---

<div class="post-metadata">

**Author:** ![moonglum](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/moonglum/32/968_2.png) [@moonglum](https://discourse.hanakai.org/u/moonglum)\
**Post date:** [September 28, 2025, 7:48am UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/6 "2025-09-28T07:48:20Z")

</div>

Thank you both! Hands-on knowledge about a solution working well was what I was searching for, so thanks for recommending Shrine. I will definitely check it out!

The last time I used Que is a few years ago, but back then it was working great. I think it is definitely worth a look!

caprover: Never heard about it, will take a look!

---

<div class="post-metadata">

**Author:** ![katafrakt](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/katafrakt/32/735_2.png) [@katafrakt](https://discourse.hanakai.org/u/katafrakt)\
**Post date:** [September 28, 2025, 9:25pm UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/7 "2025-09-28T21:25:14Z")

</div>

> [@moonglum](#):
>
> I think it is quite attractive to have a solution that can also work with transactional email providers, as this is what I commonly use in production. Anyone got any ideas here?

This is doable with Mail gem. You just need to write a little delivery method class. Here’s what I quickly assembled to support Mailgun (using their gem):

```auto
require "bundler/inline"

gemfile do
  source "https://rubygems.org"
  gem "mail"
  gem "mailgun-ruby"
end

MG_KEY = "your-key"
MG_DOMAIN = "sandbo-yours.mailgun.org"

require "mailgun-ruby"
require "mail"

class MailgunDelivery
  def initialize(_options)
    @client = Mailgun::Client.new(MG_KEY)
  end

  def settings
    {}
  end

  def deliver!(mail)
    @client.send_message(MG_DOMAIN, from: mail.from, to: mail.to, subject: mail.subject, text: mail.body)
  end
end

Mail.defaults do
  delivery_method MailgunDelivery
end

mail = Mail.new do
  from "sender@example.com"
  to "recipient@example.com"
  subject "testing mailgun"
  body "this is a test"
end

mail.deliver!

```

It could perhaps be nice if next version of hanami-mailer would contain predefined delivery methods for the popular services.

As for upload, I’d cast another vote for Shrine. This is what I use, but I agree that its maintenance story could be better.

---

<div class="post-metadata">

**Author:** ![krzykamil](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/krzykamil/32/765_2.png) [@krzykamil](https://discourse.hanakai.org/u/krzykamil)\
**Post date:** [September 29, 2025, 7:24am UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/8 "2025-09-29T07:24:06Z")

</div>

I’ll weight in with couple preferences:

**File Uploads** Shrine is the most complete, flexible and well designed tool in the market for me. Using ActiveStorage in rails was always a bit annoying to me with all the magic and bloated object interfaces. As others said, I wouldn’t be discouraged by slower commit rate in recent years - it just works.

**Deployment** I’ve used coolify and have been really happy with it. Free, full control over your system and multiple ways to deploy. Yes you need a VPS but I prefer that over any cloud solution nowadays, every day. I really recommend I am currently using dockerfile + github based deployment.

---

<div class="post-metadata">

**Author:** ![moonglum](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/moonglum/32/968_2.png) [@moonglum](https://discourse.hanakai.org/u/moonglum)\
**Post date:** [September 29, 2025, 8:06am UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/9 "2025-09-29T08:06:13Z")

</div>

> It could perhaps be nice if next version of hanami-mailer would contain predefined delivery methods for the popular services.

I did not know that you could override the delivery method on the mail gem 😮 Thanks for that! I think offering either pre-defined methods or docs on how to add the most popular services is an excellent idea 👏

**Shrine:**

So much love for Shrine \<3 I definitely need to check it out 😃

> **Deployment** I’ve used coolify and have been really happy with it.

Thanks for sharing 🙇

---

<div class="post-metadata">

**Author:** ![jaredwhite](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/jaredwhite/32/963_2.png) [@jaredwhite](https://discourse.hanakai.org/u/jaredwhite)\
**Post date:** [October 4, 2025, 7:47pm UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/10 "2025-10-04T19:47:13Z")

</div>

@moonglum I’m also investigating ways that the Bridgetown framework can promote agnostic gems / Rack solutions / etc., including a way to integrate with Hanami (aka add static sites at `/blog`, `/docs`, etc.). Bridgetown’s own dynamic server functionality is powered by Roda under the hood so it offers some compatibility with Roda plugins as well.

---

<div class="post-metadata">

**Author:** ![moonglum](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/moonglum/32/968_2.png) [@moonglum](https://discourse.hanakai.org/u/moonglum)\
**Post date:** [October 5, 2025, 7:53am UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/11 "2025-10-05T07:53:22Z")

</div>

[Pagy](https://ddnexus.github.io/pagy/) should also be on that list 🙂

---

<div class="post-metadata">

**Author:** ![moonglum](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/moonglum/32/968_2.png) [@moonglum](https://discourse.hanakai.org/u/moonglum)\
**Post date:** [October 5, 2025, 7:54am UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/12 "2025-10-05T07:54:42Z")

</div>

Very good point! I’m using Bridgetown for years for my homepage (so thanks, by the way \<3). In my head, it is stored as a static site generator, because that’s the way I use it. But you are right: It should definitely be on the radar here as well 👍

---

<div class="post-metadata">

**Author:** ![katafrakt](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/katafrakt/32/735_2.png) [@katafrakt](https://discourse.hanakai.org/u/katafrakt)\
**Post date:** [October 17, 2025, 7:55pm UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/13 "2025-10-17T19:55:30Z")

</div>

Last time I checked Pagy worked “with any ORM”, as long as it implements some kind of active record pattern. Which means it does not really work well for ROM. Perhaps now things look a bit different.

(oh wow, for some reason this post sit in draft for two weeks and I did not notice that 🙈)

---

<div class="post-metadata">

**Author:** ![alassek](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.hanakai.org/alassek/32/532_2.png) [@alassek](https://discourse.hanakai.org/u/alassek)\
**Post date:** [October 17, 2025, 9:20pm UTC](https://discourse.hanakai.org/t/a-ruby-ecosystem-for-web-apps/1307/14 "2025-10-17T21:20:34Z")

</div>

Taking a quick, superficial look at the documentation and code for this, it looks like making it work with a Relation dataset would be possible. I’m not sure about Repo.
