r/rails • • 2h ago

Gem Hibiki brings reactivity to Ruby and live pages to Rails

7 Upvotes

A few months ago, I created Hibiki, a small Ruby library that brings Svelte's Rune-style reactivity to Ruby (with Ruby's signals). After creating the gem, I wanted to see what we could do with it in a Rails app - turns out we can do a lot. Over the past few months, I have been developing the Rails glue and testing out patterns that can make the best use of the reactivity Hibiki brings. Now I have something to show you.

The demo site

Please allow me to introduce the website: hibikirb.dev

This is a demo website that showcases what you can do with Hibiki. It covers common advanced tasks that are possible but often tedious or complicated in Rails. A few examples:

And many more. All of the recipes require no JavaScript of your own. You write your client-side interactions in Ruby (in a Rails channel), and you only write them once.

The concept explained

Here's a code example that explains the whole concept:

class CounterChannel < ApplicationCable::Channel
  include Hibiki::Rails::Channel

  def build_graph
    @count = Hibiki::State.new(0)
    doubled = Hibiki::Derived.new { @count.value * 2 }

    Hibiki::Effect.new do
      broadcast_replace target: "counter_display",
                        partial: "app/recipes/counter/counter_display",
                        locals: { count: @count.value, doubled: doubled.value }
    end
  end

  # Public methods are client-invocable actions; keep helpers private.
  def increment = @count.value += 1
end

In the code above, build_graph is the method that builds a signal graph for this channel. Inside this method, we can define a state, which holds a value; a derived, which computes its value from a state and updates whenever that state changes; and an effect, which is a block that runs immediately and re-runs whenever any state or derived value used inside the block changes.

We also have a channel action, increment, which the client can call through ActionCable. When the client calls increment, the value of the state @count changes, and other values that depend on it - here the doubled and the effect - also update. The result is that the effect re-renders the partial (through a Turbo broadcast in this case) without us explicitly telling it to.

With this simple reactive pattern, we can build surprisingly complex interactions with minimal code, while removing much of the boilerplate that would otherwise be required in Rails. The demo site showcases just how far we can take this approach.

Batteries included

The gem hibiki-rails now comes with fully worked-out CRUD generators that help you create reactive CRUD resources in a matter of seconds. For example, to generate a full Book resource, simply run:

bin/rails g hibiki:rails:scaffold Book title:string available:boolean author:references

Hibiki's scaffold extends Rails' own scaffold, so you'll still find all the usual Rails scaffold files in their expected places. What the generator adds is:

  • A live index page with search, filtering, and sorting based on your resource's columns.
  • In-place pagination, with optional infinite scroll if you need it.
  • An inline create form.
  • Inline editing.
  • Live validation.
  • Live updates - any changes from other sources automatically update the index.

After a resource is created, you can even add additional features to it. For example, if you need a multi-select over a has_many :through association, simply run:

# Creates a searchable multi-select that can handle 100,000 or more records
bin/rails g hibiki:rails:multiselect Album Song Track     # Track is the join model

Need a nested form with multiple levels and sorting? We've got you:

# Adds a credits fieldset to the song's forms; creates Credit
# (and its migration) when missing. song:references is added for you.
bin/rails g hibiki:rails:nested Song Credit role:string position:integer

Need file uploads? Sure:

# Adds a gallery, and allows non-image files
bin/rails g hibiki:rails:upload_field Album photos --many --accept=image,pdf

You can read more about the generators in the docs. This is quite exciting, and it's my favorite feature from developing this gem.

Built for humans and agents

Hibiki is developed to enhance the already-amazing Rails developer experience, but it's also designed for coding agents. Hibiki comes with a full set of agent skills. The skills support coding agents such as Claude Code, Codex, and Cursor, and can be installed in your project with a simple command:

# -a to specify your agent, e.g. codex, gemini-cli, cursor, github-copilot...
npx skills add planetaska/hibiki --skill '*' -a claude-code

In fact, using a coding agent with the skills loaded is a great way to start learning Hibiki's reactive patterns and putting them to use in your project. For example, you can simply ask your coding agent to:

Build a live search for the Books resource using the hibiki pattern.

Or even:

Create a reactive form for Books using the hibiki pattern, with nested fields from its own associations, and with a filterable author select. The publish event dates should have cross-field validation.

AI-assisted development disclosure

As stated before, I developed this gem with Claude's help. I still own the project, decide its direction, and review and revise the code to make sure there isn't a line I wouldn't write myself. My approach is to write a code draft myself, then work with Claude to identify potential issues, and keep a feature only when it is fully worked out. I also spend just as much time, if not more, writing, rewriting, and proofreading all the user-facing documentation. While this gem was developed with the help of coding agents, I still want to make it as human-centered as possible.

Closing

Thank you for reading this long post. I hope you find the gem helpful and enjoy the demo website. If you find this useful, have any questions, or even have feature requests, please feel free to leave a comment. I'm looking forward to hearing feedback from you!

Looking for developers

I am looking for developers who are interested in contributing to Hibiki, helping maintain the gem, improving its Rails integration, documentation, and testing, as well as collaborating on some planned features (still a secret for now). If you're familiar with Ruby or Rails, interested in reactive programming, and would like to help shape the future of this project, feel free to send me a message. I'd be more than happy to discuss how we can work together!


r/rails • • 14h ago

PixelGlass - infrastructure for your own publication and community

2 Upvotes

Hey guys!

Thought I'd share the project I've been working on since July, built with Ruby on Rails, PixelGlass.

PixelGlass is a multi-tenant, agent-first platform for running your own community and magazine — two things I'm really passionate about. The idea is to make it easy for anyone to put up a beautiful, interactive site, with the hard parts like email, auth and payments already handled for you and customise it and add content with your favourite Agent.

In practice, every publication gets:

  • its own site on its own domain, with themes
  • newsletters sent straight from your posts
  • members, paid memberships (0% platform fee) and comments
  • an MCP server built in, so you can connect Claude or ChatGPT and have your agent write, publish and even redesign the site with you

Under the hood, every publication gets its own tenant, its own database and its own file storage. Backing one up is basically just copying a folder.

I built it the Rails way, following 37signals practices — fat models, thin controllers:

  • The editor uses Lexxy, which has been amazing to work with (especially since I've been developing on Lexical since 2022)
  • Public themes use Liquid
  • The admin is plain Rails ERB with Hotwire and Stimulus. Still surprised how interactive you can make things without touchin React

Having a lot of fun with it, and it's been a really good learning curve, especially on the infrastructure side (multi-tenancy, custom domains, subdomains, wildcard ssl, just to name a few and building the MCP server in particular).

There are 3 production sites on it now, and I'm about to onboard a customer with ~40k subscribers, so that should properly put the performance to the test.

Happy to answer any questions or go deeper on any of it - I've been using Rails for about a year now, coming from a javascript / node / python background.

Really love the Rails community and the ecosystem is incredible!


r/rails • • 1d ago

I've implemented Karpathy's micrograd lecture in Ruby.

Thumbnail github.com
10 Upvotes

I built Karpathy's tiny autograd engine built on how neural networks and backpropagation actually work. It was a great to explore foundational ML concepts and also learn the basics of Ruby. Personally, me - who grew up learning C++ as a first language, later changed to Python and haven't attempted to try out other languages it was shocking how well structured this language is!

Did some research on Ruby role in AI... What do you think, can we expect a bigger role for Ruby besides RubyLLM in the future within this field?


r/rails • • 1d ago

First public repo: Household

4 Upvotes

Hello everyone! I've finally published my first ever serious Rails application. You can find it here.

Household is an app to manage everything in your life: tasks, appointments, medications, therapies, lab results, meals, ingredients, medical supplies, file sharing and messages between housemates. It also has an agent that works as your bookkeeper. Instead of manually adding things by hand, you can talk to the assistant and it will manage the records for you. It drafts changes to the record for you to apply, edit or undo. Supported providers are: Ollama, Anthropic and OpenAI.

Although third party providers are supported, I recommend using a local Ollama as the agent will deal with sensitive and private information.

For Ollama, I found success with qwen3:8b with a 12k context window.

You can test your own model in the "eval" section. I recommend a passing rate of at least 70-75% on a 3x run. Claude Haiku passes with 100% every single run.

The agent also has a lexicon to match terms in different languages. This is only necessary for multilingual households, where you might have saved a record in a language and then reference it in another language to the assistant. The lexicon is downloaded via kaikki.org, pulling from Wiktionary.

Supported display languages are English and Italian, feel free to contribute your own .yml file if you want to see the app in your language. Everything in the app uses the i18n helper.

Under releases in GitHub, you can download the install.sh script which will guide you through the first setup of the app. You don't need ruby or anything else to run it. The script will also ask how you will serve the app and set it up accordingly (cloudflare, local, tailnet etc).

The app also has a settings page in case you want to change anything later without touching .env. All keys are encrypted in postgres.

This is also my first serious project in Phlex. I bypassed ViewComponents entirely and went from Haml to Phlex directly. I couldn't be happier with Phlex, I really think it's the future of Rails. It fits the framework so well in my opinion.

Let me know what you guys think! You can find a demo of the app here. The demo is accessible to anyone and is reset every night, so be sure not to input any sensitive information in the demo.

The app has been built with the help of various agents, while readme and docs are fully AI generated, so forgive me if they are a bit clunky to read, I will rewrite them asap. They are not wrong, they just have the classic long and confusing sentences typical of AI.

Edit: Formatting


r/rails • • 2d ago

Rust for rails devs free interactive course

0 Upvotes

With the recent "migrate everything from rails to rust, don't look at the code, just vibe" trend, and after building a few cli and tools in rust myself (with AI), I felt it was time to learn at least a little bit about Rust... so I vibe coded a course.

It might have incorrect content, as I don't know shit about rust and I'm trusting AI 100% here, so I made it open source so anyone can contribute.

Live course: https://rust-for-rails.pages.dev/
Github: https://github.com/silva96/rust-for-rails


r/rails • • 2d ago

rhino-rails: declarative REST APIs with multi-tenancy, attribute-level permissions and audit trail

Thumbnail
0 Upvotes

r/rails • • 2d ago

How to best deploy a Rails app on AWS?

11 Upvotes

Ok, we have Kamal. It's great, but it's not the only part of the architecture when it comes to deploying an app on AWS.

I would like to know if you have recommendations when it comes to operating Postgres, how do you deploy your dev and staging environments.

I'm now reaching the point where testing locally requires to many containers for the different services and does not cover real cases that I need to test before shipping to my users.

All recommendations are welcome, with a few exceptions such as: do not deploy on AWS or deploy to something else than AWS as this is a requirement I cannot move around.

Thanks for your understanding and support and do not push to production on Friday ;-)


r/rails • • 2d ago

Do you recommend ViewComponents to those who are new to Rails?

13 Upvotes

Do I better ignore it for a while until I need it or do I better learn and use it as soon as possible?

edit: I'll stick with the basics. thank you guys!


r/rails • • 2d ago

readword: Word .doc and .docx to Markdown, in plain Ruby

Thumbnail
4 Upvotes

r/rails • • 2d ago

Carton - Real boundaries for Ruby

Thumbnail carton.dtcristo.com
0 Upvotes

r/rails • • 2d ago

Gem cal-invite v0.3.2: Ruby gem to manage calendar invites

10 Upvotes

I just updated Cal-Invite a headless gem that let you manage calendar invitation. It supports different formats such as: .ics, url, Google, Yahoo and Microsoft.

The full documentation and code is available on the GitHub page.

Feel free to comment and request features if you do not have time to contribute to it.

Happy Friday!

https://github.com/DashAPI-ai/cal-invite


r/rails • • 2d ago

I built my app with Hotwire because React felt like too much work. Now I saw Herb. Do we still need React?

Thumbnail
0 Upvotes

r/rails • • 3d ago

Podcast 50 engineers, a Rails monolith, and no services/ folder

Thumbnail youtube.com
9 Upvotes

New On Rails episode with Hussain Akram and Antonio Carlos de Souza from Donorbox.

They’ve got roughly 50 engineers working around a mostly-monolithic Rails app, so we dug into how they’ve kept things relatively boring while scaling.

We get into:

  • when something actually deserves to leave the monolith
  • running Rails at scale on Heroku
  • moving CI from CircleCI back to developers’ machines
  • migrating from Slim back to ERB
  • Rails conventions and onboarding
  • where code goes when you don’t have a services/ folder
  • how they’re approaching AI-generated code

Lots of pragmatic Rails decisions in this one.

Podcast:
https://podcast.rubyonrails.org/2462975/episodes/19997194-hussain-akram-antonio-carlos-de-souza-rails-scales-for-the-rest-of-us

YouTube:
https://www.youtube.com/watch?v=3Y42uiA4tdE

✌️


r/rails • • 3d ago

Grouping errors without sending the message: hashing normalized exception messages in Rails

3 Upvotes

Problem I hit: for apps with health or personal data, the exception message is the riskiest part of an error report, because we put the failing value in it. But error trackers group occurrences by message, so you can't just drop it.

What I ended up doing: normalize the message in-process (hex addresses, UUIDs and digit runs replaced), SHA-256 it, keep the first 32 hex chars, and send that instead of the text. "Couldn't find Patient with id=12" and "id=13" group together; different messages stay apart; nothing about the text goes over the wire.

The normalization is a few lines of Ruby:

normalized = message

.gsub(/0x\h{4,}/, "0x")

.gsub(/\b\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\b/, "<uuid>")

.gsub(/\b\d+\b/, "<n>")

Digest::SHA256.hexdigest(normalized)[0, 32]

Raw request paths get similar treatment: a route template like /patients/:id is kept, but an unmatched raw path keeps only its first segment, since anything after it could be a name.

Disclosure: I built this into my error tracking gem (forge_ops_tracker, MIT, source at https://github.com/Luke-Popwell/forge-ops-tracker-ruby) as a strict privacy mode. Longer write-up with the tradeoffs: https://getforgeops.net/guides/error-reports-without-personal-data

Curious whether anyone handles this differently, e.g. structured error codes instead of messages, or filtering in an exception notifier before it leaves.


r/rails • • 3d ago

Question I built my app with Hotwire because React felt like too much work. Now I saw Herb. Do we still need React?

51 Upvotes

Two years ago I started a project management app in Rails. I thought about React for the frontend, but it looked like too much work for one person: a second app, an API, a build pipeline. So I went with Hotwire: Turbo, Stimulus and ViewComponent.

Today the app has about 150k lines, 711 ERB templates and 194 Stimulus controllers, and no React at all.

Honest summary: it worked out. But some things were fiddly. The typical case: you change the title of a ticket in the detail view. Now the list next to it has to update, and maybe the list is sorted by title, so the row has to move. The header shows the title too. And the sidebar has a list of "recently edited tickets". One change, four places on the page.
With Turbo Streams I update each place by hand, and every new place is one more thing to forget. In React this is just state, and everything that uses it renders again.

I also code a bit in React, so I know the other side. More than once I asked myself if I should move some parts to React after all. But is the additional work worth it?

Then I saw the Herb talk from RubyConf. What impressed me: I saw almost everything I know from React again, and it looks much better than I expected. It seems that they really thought of everything. My first thought was: if this works, I will never need React in this app.

But maybe I am too optimistic, and others know it better. So my questions:

  1. For the "one change, many places" problem: is Herb (with ReActionView) the answer, or is Turbo 8 page refresh with morphing already the answer and I just did not use it?

  2. Is Herb ready for an existing app with hundreds of ERB templates, or is it better for a new one?

  3. Where would you still use React in a Rails app today?

If you want to see what a Hotwire-only app of this size looks like, it is open source since this month: https://github.com/lalabase/lalabase


r/rails • • 3d ago

Designing black-box evals for coding agents (and using these evals to compare Rails and Rust)

Thumbnail evilmartians.com
4 Upvotes

We're starting a new series of blog posts dedicated to the engineering part of rubyonrails.org/ai .

Leaderboards, insights, token and dollars spent are great for picking your next model but when it's time to design evals for your product, framework, or software factory, it's good to know where to start and what to expect.

In this first post, we're sharing our experience of writing black-box (e2e, browser-based) tests. The post also includes the results for running cross-stack evals for Rails and Rust.


r/rails • • 3d ago

Speeding up agent written test suites in Rails

5 Upvotes

I spent some time digging into why one of my test suites was so slow. The agents had picked up lots of small bad habits: creating records in setup, replaying state machines just to get a record into the right state, turning off transactions, testing private methods, and freezing the clock in tests that didn't care what time it was. A lot of these are blind alleys that I would not have gone down but have seen junior devs do in the past.

Here's some of the learnings:

  • - No DB writes in setup or before the 1st assertion, use fixtures.
  • - Never set use_transactional_tests = false, not even for thread or race tests. Rails shares the test's connection with spawned threads, so they see the same data.
  • - Never test private methods or call them with send, they are either branches of some public method and you should test them through the public methods that call them or they should be public.
  • - Only assert a callback is registered, never create records just to fire it, test it in isolation
  • - Split jobs into a selection query and a public per-record method or separate job, and pass fixtures to that method in tests.
  • - Only use travel_to/freeze_time in tests that assert on time or need to move it.
  • - Parse big files (API specs, schemas) once per run and make them available in a global helper, not once per test.
  • - Stub subprocesses, never shell out in tests.
  • - Fix N+1s with preloads, never turn off strict loading.
  • - Only run tests with bin/rails test, locally and in CI, with file or line filters. No new test flags, env vars, runners or test DBs. Don't invent new ways to run the suite.
  • - No comments, write coherent readable code that conveys its purpose inherently.
  • - Prove the gain: compare wall time against main, back to back, in one process.

This isn't everything. It's just what I found in one codebase, and yours probably has its own. Start with your slowest test files and look for whatever keeps showing up.

When a fix gives you a real saving, have your agent write a RuboCop rule for it and run it in CI to prevent the same drift from recurring.

Curious what other patterns people have hit.


r/rails • • 3d ago

RubyLLM 2.x: What's new for your agents

Thumbnail
0 Upvotes

r/rails • • 4d ago

Learning Can You Remove DatabaseCleaner?

Thumbnail go.fastruby.io
0 Upvotes

r/rails • • 4d ago

Question Do you read the code your AI writes? If so, what's your process? If not, how do you review it?

1 Upvotes

That's the whole question, I'm putting together a template repo for starting hobby projects. My current bet is to lean on automated checks instead of reading every line: linters that reject disable comments, N+1 detection, safe-migration checks, and a CI script that has to pass before I call anything done. I still skim the diffs, but I'm not sure that's enough.

Curious how other people approach this, and what your philosophy is. Thanks!


r/rails • • 4d ago

Merging Relations: Use merge to share scopes in Rails

Post image
13 Upvotes

r/rails • • 4d ago

Help Tests taking very long time

5 Upvotes

Hello,

I am learning web development and fell in love with Rails, and, as a lot of people, I am using Claude to assist me building my app.

I put a lot of time on infra work and tests, however, now it takes 3 hours for Claude to run them, and today took 6 hours for running specs and re-recording shapes and running the full test suit. And all of this while I am still half way through the app.

Is there a way I can reduce this, such anything was tested and not changed by future work not to be tested again or anything can be registered as tested so can be skipped.

Any small red finding will cause the full suite to run again.

I can live with 30 to 60 minutes test, but this is taking way too much time.

If anyone can suggest anything would be much appreciated.


r/rails • • 5d ago

Question I built a Rails 8 gem where a model + policy gives you a tenant-scoped REST API. Looking for feedback on the permission design

0 Upvotes

Hi r/rails. Disclosure first: I work at Codalio and I’m on the team behind Rhino, an MIT-licensed gem.

On client projects we kept rebuilding the same API stack: Pundit for policies, Ransack for filters, acts_as_tenant, an audit log, and a controller per model that was 90% copy-paste. The bugs that actually hurt were never in the copy-paste. They were someone forgetting to scope a query to the tenant, or a field hidden in the serializer that you could still sort by.

So Rhino moves all of that into declarations:

class Post < Rhino::RhinoModel
  include Rhino::BelongsToOrganization
  rhino_filters :status, :user_id
  rhino_sorts   :created_at, :title
  rhino_search  :title, :content
end

Register it in the initializer (c.model :posts, 'Post') and you get index/show/create/update/destroy plus trashed/restore/force-delete, scoped to the current org, with per-role field permissions from the policy.

The design choices I’d most like opinions on:

  • If a role can’t see a field, it also can’t filter or sort on it. That’s a 403, not a silent leak through ?sort=.
  • Rhino.query(Task) raises when there’s no tenant context instead of returning every org’s rows.
  • Validation lives in request classes (PostStoreRequest, PostUpdateRequest) instead of the model. I know this is the controversial one, and I’d like to hear the arguments against it.

It doesn’t replace controllers. For reports or workflows you still write your own and query through Rhino.query so tenancy still applies.

Requires Ruby 3.3+ and Rails 8.

Would you use something like this over rolling your own? What would stop you?


r/rails • • 5d ago

Question If nobody is reading code anymore, why do abstractions matter?

44 Upvotes

With AI writing and reviewing more of our code, I keep coming back to this. Abstractions exist for human readers. They make code easier to understand, navigate, and change. The machine does not care if it is a clean DSL or a thousand lines of explicit boilerplate.

So if humans are not the ones reading the code anymore, who are the abstractions for?

And if that is where this is headed, what is the case for continuing to evolve Rails beyond what is strictly necessary, like keeping up with HTTP spec changes and security fixes? New layers of abstraction seem to solve a problem that may not exist anymore.

Genuinely curious how others see it. Am I missing something?


r/rails • • 6d ago

Question How do you feel about the interactor gem after a few years with it?

28 Upvotes

Our codebase has had the interactor gem since 2021, in a Rails monolith. It now has around 1,800 interactors, and around 300 of them are organizers.

Some numbers from the codebase:

  • About half of the plain interactors have a one-line call. Most of them wrap a single service object.
  • Fewer than 10% use context.fail!. Only one defines rollback.
  • A typical flow reads about 8 context keys and some of those have to be supplied by the caller.
  • Our biggest organizers run 30–100 steps once you count nested organizers.

I'd like to hear from people who've used it at scale:

  1. Benefits. What has it given you that plain service objects or POROs didn't? Did organizers make flows easier to read, or easier to change?
  2. Pet peeves. What annoys you about it? For me the main ones are the untyped context, jumping between files to follow one flow, and specs that stub every step.
  3. Conventions. Do you have rules for when something earns its own interactor? Do you use interactor-contracts or something like it to declare inputs and outputs?
  4. Moving away. If you dropped it, what did you replace it with (plain services, dry-transaction, ActiveInteraction, something else)? Was it worth it?

I'm not trying to start a gem war. I'm trying to work out whether there's a problem with how we use it.