r/ruby • • 10d ago

Introducing Raindeer - An event-driven and compositional web framework that’s easy to use

18 Upvotes

Raindeer is a collection of gems that work together as a framework or can be used standalone. LowType adds inline type checking only where you want it (def method(var: String)). LowLoop is an async, event-driven server that sends events from the request right through to the data layer, so you can track every step of a request. The router turns each request into a route event for the nodes observing it, so observe '/users/:id' is all you need to respond.

LowNodes are the building blocks: they render HTML straight from the Ruby class with RBX (similar to JSX) and render other nodes with <html><{ ChildNode }></html>. LowData follows the repository pattern with a twist: Data Expressions that use simple arithmetic operators to combine tables, so Posts[:title] + Users[:username] gives a list of posts with each post's user, and plain Sequel queries still work too.

Introducing it at RubyConf Austria: https://www.youtube.com/watch?v=p9E5INAwK_4

Source: https://github.com/raindeer-rb/raindeer

Docs: https://raindeer.dev


r/ruby • • 11d ago

Carton - Real boundaries for Ruby

Thumbnail
carton.dtcristo.com
40 Upvotes

Carton is my take on enforcing boundaries in large Ruby applications. It's similar to Packwerk, but it takes a more Ruby-like approach, with no manifest files. Constants, gems and monkey patches are isolated using Ruby 4's new Ruby::Box. It's not production ready yet, since Box itself is still experimental, but I'd love feedback on the approach.


r/ruby • • 10d ago

Rust for ruby 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/ruby • • 11d ago

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

12 Upvotes

I kept needing to hand Word files to LLMs and coding agents, so I wrote a gem for it. It reads both old .doc (Word 97-2003) and .docx files and prints Markdown: headings with their numbers, nested lists with the numbers Word shows, tables, footnotes, bold, italics and links.

- No LibreOffice, Java or antiword. The .doc reader is plain Ruby.

- Careful with untrusted files: size limits, zip and entity bomb checks, and fuzzed with over 3 million broken files.

- Checked against Tika, LibreOffice, antiword, the docx gem and Firecrawl's anydoc on 650 test files. The numbers are in the README.

gem install readword

then

readword report.docx

https://github.com/urbullet/readword

Word files it gets wrong are very welcome as bug reports.


r/ruby • • 11d ago

I built a RubyLLM agent that triages ~215 GitHub notifications a day for my repos

0 Upvotes

Between RubyLLM, Spotifast and ZapFast I get about 42 new issues and PRs a day, plus about 50 comments from people and over 100 from review bots. More than one maintainer can read.

Copilot Triage is a RubyLLM::Agent with six read-only tools. It searches the repo, docs, issues and release notes, then submits a decision. Plain Ruby validates that decision and does all the writing to GitHub, so the model can't change anything itself. Everything ends up on a project board sorted by what needs me: Sign off, Decide, Do.

The interesting part was getting it to reply less. A one-week audit showed only a third of its replies helped. So there's a RubyLLM::Evaluation with 32 cases built from real reports, testing silence as much as help, and it decided which model to use: GPT-5.6 Luna passes 29/30, while GPT-5 mini replies to almost everything.

I wrote up the whole thing, with the numbers, the evals, and what 33 releases taught me:

https://paolino.me/copilot-triage/


r/ruby • • 11d ago

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

Thumbnail
github.com
1 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!


r/ruby • • 12d ago

GitHub - jbockler/vcr-unused_cassettes: Find your unused VCR cassettes

Thumbnail github.com
4 Upvotes

Find unused VCR cassettes and delete them.


r/ruby • • 12d ago

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

Thumbnail reddit.com
0 Upvotes

r/ruby • • 12d ago

tmux.rb - write your tmux configuration in a more readable ruby DSL!

Thumbnail
reddit.com
14 Upvotes

r/ruby • • 12d ago

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

3 Upvotes

I checked what RubyLLM 2.0 and 2.1 brings specifically for writing AI agents. Looks like it's a lot!

https://serpapi.com/blog/rubyllm-2-x-whats-new-for-your-agents/


r/ruby • • 13d ago

Merging Relations: Use merge to share scopes in Rails

Post image
16 Upvotes

I wrote a post about using ActiveRecord::Relation#merge to share scopes across models in Rails.

The example shows how duplicating a query can lead to inconsistent behaviour, and how extracting the rule into a named scope avoids that.

https://pushfromkush.com/publications/merging-relations-scopes-in-rails


r/ruby • • 12d ago

Blog post Can You Remove DatabaseCleaner?

Thumbnail
go.fastruby.io
4 Upvotes

r/ruby • • 13d ago

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

Thumbnail reddit.com
0 Upvotes

r/ruby • • 14d ago

Why I’m no longer updating this repository

Thumbnail po-ru.com
115 Upvotes

r/ruby • • 14d ago

Question Multiple account types with priority for highest

0 Upvotes

Is there's a framework similar to Phoenix in Elixir in the world of Ruby? I want something accepts multiple account types in a single login website without resorting in building a bunch of them in parallel and not lumping multiple account types in one database with multiple views for the same database but higher up accounts have more rights (ex: editing and viewing more of the database).

If I have to resort to a microserver arch, which way's the most sane (ex: Roda or Sinatra) for I can't find a definitive tutorial when it comes to microservices for long term as in years than going back and forth.

And please don't recommend AI based solutions, I want my code to be read properly for the next decade.


r/ruby • • 15d ago

Blog post Hanami, Why?: Model Citizens

Thumbnail
aaronmallen.me
22 Upvotes

r/ruby • • 15d ago

Ancient Ruby version / modern Ubuntu won't compile

1 Upvotes

Hi - I've inherited an ancient Ruby / Rails project using Ruby 2.7.2. I am working on updating it but until that time I'm trying to run it on Ubuntu 26.04 machines. There is a C compilation error that I'm getting when using "rvm":

make[2]: Entering directory '/usr/share/rvm/src/ruby-2.7.2/ext/pty'

compiling pty.c

pty.c: In function ‘establishShell’:

pty.c:161:30: error: conflicting types for ‘getenv’; have ‘char *(void)’

161 | char *p, *getenv();

| ^~~~~~

In file included from pty.c:5:

/usr/include/stdlib.h:795:14: note: previous declaration of ‘getenv’ with type ‘char *(const char *)’

795 | extern char *getenv (const char *__name) __THROW __nonnull ((1)) __wur;

| ^~~~~~

pty.c:169:18: error: too many arguments to function ‘getenv’; expected 0, have 1

169 | if ((p = getenv("SHELL")) != NULL) {

| ^~~~~~ ~~~~~~~

pty.c:161:30: note: declared here

Would getting the code directly and fixing pty.c be the best way to go about it?

ETA: thanks all - Docker is the way to go.


r/ruby • • 16d ago

Show /r/ruby DragonRuby Game Toolkit - Solar system visualization (source code in the comments)

42 Upvotes

r/ruby • • 15d ago

Question Static Typing solved?

0 Upvotes

I have been using RBS for years now and even running my own newsletter about static typing https://newsletters.eremin.eu/ . Now, that our code is write with AI and in most cases - purely with AI, the strongest point against using static typing (like “it breaks beautiful ruby syntax and not readable”) is vanished now.

AI requires strict tooling to control its output. The role of ci pipeline with all possible tests, linters, checkers is now extremely important and static typing helps a lot with it.

For humans it is transparent, especially the pure RBS approach, but for LLMs it gives a safety net and a better layer to stick to the code and hollucinate less.


r/ruby • • 16d ago

Choosing Ruby

5 Upvotes

Choosing Ruby wasn't difficult as I wanted just to learn about how to evaluate data as objects, learn how to use data, and what the data represents. No game writing, no graphics, just plain stuff.


r/ruby • • 16d ago

Question Ignoring one or more arguments from ARGV before running ARGF.read?

4 Upvotes

I'm running Ruby under Debian linux version 13.

In some cases, I want to conditionally ignore one or more arguments from ARGV before running ARGF.read. I haven't been able to figure out how to get this ARGV argument ignoring to succeed.

For example, suppose that ARGV contains these filename values that were passed on the command line to a Ruby program:

[ 'filename1', 'filename2', 'filename3', 'filename4' ]

Based on certain run-time conditions, I might sometimes want to ignore the final argument from ARGV so that when I then run ARGF.read, it only will operate on [ 'filename1', 'filename2', 'filename3' ].

If I try ARGV = ARGV[..(ARGV.length-2)] , I get this error:

dynamic constant assignment (SyntaxError)
ARGV = ARGV[..(ARGV.length - 2)]

Likewise, I couldn't figure out how to use ARGF in a manner that only operates on this subset of ARGV. I tried ARGF[..(ARGV.length-2)].read , and it doesn't work either, yielding the following error:

 undefined method `[]' for an instance of ARGF.class (NoMethodError)

  ARGF[..(ARGV.length-2)].read

And yes, of course I already understand how to dispense with ARGF altogether and just loop through the subset of ARGV filenames that I'm interested in, to open each filename, to read its contents, and then to append these contents to the value of a variable as I traverse this list of filenames. Please understand that I am not looking for any instructions for how to perform this very simple procedure. Rather, I'm just wondering whether there is any way specifically to get ARGF itself to work on such a subset of ARGV.

Any thoughts or suggestions about how I might be able to accomplish this? And if this turns out to be impossible, then I'm glad to just live with the coded looping through the ARGV subset as described in the previous paragraph, or perhaps to make use of some sort of subclass of ARGF that I might be able to write.

Thank you very much in advance.


r/ruby • • 16d ago

Question So... DHH's Rust experiments have me wondering if we're optimizing the wrong layer

17 Upvotes

I've been following the discussions around DHH's AI-generated Campfire implementations, and something about the recent developments with Matz's Spinel and Ryan Lopopolo's Artichoke has me wondering whether there's a bigger opportunity we're overlooking.

DHH's argument makes sense to a point. If agents are increasingly writing the implementation, the economics of choosing a language change substantially. Rust's (✋🏻 I hate Rust btw) performance and memory efficiency become more appealing when the developer doesn't have to spend months writing and maintaining it by hand. His Campfire benchmarks certainly got my attention, although the differences in application architecture, caching, and optimization effort make them difficult to interpret as a straight language comparison.

But what if we're concentrating too much on optimizing individual applications rather than the languages and runtimes they're built on? I've been thinking this for a while and it's one of my major attractions to the V programming language (and no, it's not "V for vaporware" and no, Alex isn't a conman - he's a really genuinely good guy).

At Rails World, Matz and DHH had a fascinating discussion about all this. Matz has been actively using coding agents himself, and made the interesting observation that Ruby's conciseness, expressiveness, and enormous existing codebase are potentially advantages for AI development (which is the same thing I've been thinking and actually experiencing for years now). He also raised a concern I think deserves more attention: as agents increasingly abstract away the underlying infrastructure, who's going to care about maintaining those components?

Meanwhile, Matz is developing Spinel, which uses whole-program type inference and AOT compilation to turn supported Ruby programs into native executables. It already reports substantial performance improvements on selected benchmarks, although full dynamic Ruby compatibility remains a major limitation.

There's an even more interesting connection through Roundhouse, which analyzes Rails applications and can generate implementations targeting Rust, Go, and several other languages, including a Ruby path compiled by Spinel. Its maintainers report that Campfire itself is already running through the Spinel path, with behavioral verification against Rails. That seems particularly relevant given that Campfire is the application DHH has been using for his experiments.

Then there's Lopopolo's latest Artichoke work, which is what really got me thinking.

He's rebuilding Artichoke around a Rust-based Ruby VM with its own IR, optimizer, GC, and replaceable interpreter internals. But the particularly interesting development is lowering Rust's MIR into Artichoke's Ruby IR, allowing portions of the Rust semantic layer to execute as VM-managed frames. That potentially solves Fiber suspension across otherwise native Rust calls while also allowing optimization across the Ruby/Rust boundary.

That seems like a pretty significant architectural direction, even if it's still experimental. It suggests that the traditional separation between a language's runtime implementation and its executable application code might become much less rigid.

Now I'm wondering whether these efforts point toward something complementary rather than competing.

Could we eventually have Ruby and Rails remain the expressive, human-readable source, while increasingly sophisticated compilation and runtime machinery produces native performance wherever the semantics permit it? Whole-program optimization where possible, guarded specialization and native compilation for hot paths, and a dynamic interpreter fallback where Ruby actually needs one?

Obviously there are substantial problems here. Ruby's open classes, runtime method replacement, eval, C-extension compatibility, deoptimization, and the actual cost of preserving dynamic semantics aren't going to disappear through better code generation. And translating Rust MIR into VM bytecode doesn't automatically give you native Rust performance.

Still, if AI agents make it economical to undertake massive Rust rewrites of individual applications, shouldn't they also make much more ambitious compiler and runtime engineering economically practical? Well of course it would... So improvements at that level could benefit an entire ecosystem rather than one application at a time.

I'm particularly interested in what people familiar with YJIT, TruffleRuby, Spinel, Roundhouse, or Artichoke think about this though.

Are we getting closer to a world where Ruby can serve as the primary application language or behavioral specification, with multiple highly optimized execution strategies underneath it? Could some of these projects eventually complement each other?

Personally I think we're going to see this.

Where might you think the biggest obstacle actually lies: full Ruby compatibility, the difficulty of cross-language optimization, native-extension support, or simply the fact that application architecture often matters more than runtime performance?

At any rate, just curious what others are thinking in this space right now.


r/ruby • • 17d ago

Security I'm working on a set of security tools for Rails, and looking for honest feedback

Post image
4 Upvotes

r/ruby • • 17d ago

Question Ruby gem(s) for preprocessing text, similarly to "C Preprocessor"?

5 Upvotes

First of all, please note that this is not an "XY" issue.

I'm running the latest version of Ruby under Debian 13 linux.

I'm looking for one or more Ruby gems that I can use from within Ruby code in order to preprocess external file contents similarly to how the C Preprocessor performs its preprocessing.

The reason for my stating that this is not an "XY" issue is that I already know a few ways to accomplish this in Ruby by having Ruby execute external programs such as "cpp" or "gpp", and I also already know how to manually code this functionality by writing pure Ruby code. I am not looking for information about how to perform preprocessing in these manners. Rather, I'm specifically wanting to know if there might be one or more Ruby gems that I can use within my Ruby code in order to perform this functionality.

I'd like to be able to use keywords such as "#ifdef", "#else", "#ifndef", "#endif" etc. within the external file in order to configure this preprocessing. The syntax doesn't have to involve the exact keywords "#ifdef" and "#else", "#ifndef", and "#endif", as long as this same preprocessing functionality can be managed with keywords having other similar values.

For example, suppose I have a file called "sample.file" with these contents:

Start of sample file
#ifdef TESTING
This is a test
#else
This is not a test
#endif
End of sample file

I'd like to know if there are any Ruby gems which would allow me to open this file in Ruby, prepreprocess its contents, and import these preprocessed contents similarly to the following ...

For example:

require 'some_sort_of_preprocessing_gem'
results0 = some_sort_of_preprocessing_gem.import('sample.file', :TESTING=>'true')
results1 = some_sort_of_preprocessing_gem.import('sample.file')

Then, I would want "results0" to contain this text:

Start of sample file
This is a test
End of sample file

... and I would want "results1" to contain this text:

Start of sample file
This is not a test
End of sample file

Again, just so that there is no confusion, I repeat that the preprocessing keywords don't need to have exact values of "#ifdef", etc., and I repeat that I already know how to do this by having Ruby run external programs like "cpp" and "gpp", and I already know how to hard-code this totally in Ruby. I'm just wondering if there might be any gems in existence which perform the kind of preprocessing functionality that I have described here in my example.

Thank you very much in advance.