Rubyland

50 min read Original article ↗

You are iterating on a design. Maybe you are redesigning your dashboard. Maybe you are trying three different layouts for a landing page. Maybe Claude just gave you four variations of a pricing table and you need to pick one.

Here is the problem: every time you make a change, you overwrite the last version.

Designing directly in code has become incredibly fast with LLMs. You describe what you want, you get working HTML and CSS back in seconds. But the speed creates a new problem. You generate version one, tweak the prompt, generate version two, and now version one is gone. You want to compare them. You want to send both to your designer or PM and ask which one feels better. You want to open…

Authors: Vladimir Dementyev, Principal Backend Engineer, and Travis Turner, Tech EditorTopics: Real-time, AI, Open Source, Real-time features, Ruby on Rails, Hotwire, WebSocket

Real-time LLM streaming sounds simple—until it isn’t. A Rails-focused look at hidden pitfalls, AnyCable’s fixes, and the future of durable streams.

By the end of 2025, it's hard to find a web application that doesn't have AI-powered features (or that hasn't tried to incorporate them). And when reflecting AI-generated content in a UI, LLM response streaming capabilities are essential. They enable us to provide feedback quickly, reduce the perceived slowness of AI, and thus improve the UX. But even though frameworks and…

Introduction

Modern observability platforms thrive on structured data. They can parse JSON, extract fields, build dashboards, and alert on specific conditions. But Rails has traditionally given us Rails.logger, which produces human readable but unstructured log lines.

Parsing these logs for analytics is painful. We end up writing regex patterns, hoping the log format doesn’t change, and losing valuable context along the way.

Rails 8.1 introduces a first class solution: the Structured Event Reporter, accessible via Rails.event.

Before

Before this change, logging in Rails meant working with unstructured text.

Rails.logger.info("User created: id=#{user.id}, name=#{user.name}")

This…

With the end of 2025 near, let’s build something fun: a snow effect for your (Rails) app or site (built with Perron?) using one Stimulus controller. Snow will fall from the top of the viewport, pile up at the bottom and you can sweep it away by dragging your mouse. Give it a try on this page! 😊☃️

Creating the basic controller

Start with the controller structure and lifecycle methods. Create a new Stimulus controller:

// app/javascript/controllers/let_it_snow_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  connect() {
    this.#startSnow()
  }

  disconnect() {
    this.#stopSnow()
    this.#meltSnow()
  }

  // private

  #star…

We are pleased to announce the release of Ruby 4.0.0-preview3. Ruby 4.0 introduces Ruby::BOX and “ZJIT”, and adds many improvements.

Ruby::BOX

A new (experimental) feature to provide separation about definitions. For the detail of “Ruby Box”, see doc/language/box.md. [Feature #21311] [Misc #21385]

Language changes

  • *nil no longer calls nil.to_a, similar to how **nil does not call nil.to_hash. [Feature #21047]

  • Logical binary operators (||, &&, and and or) at the beginning of a line continue the previous line, like fluent dot. The following two code are equal:

      if condition1
         && condition2
        ...
      end
    
      if condition1 && condition2
        ...
      end
    

Core classes updates

Note: We’re only listing outstanding class updates.

  • Kernel

    • Kernel#inspect now checks for the existence of a #instance_variables_to_inspect method, allowing control over which instance variables are displayed in the #inspect string:

        class DatabaseConfig
          def ini…

Campsite has some of my favorite UI styling on the web. Naturally, I cracked open their source hoping to learn something. What I found: React components rendering <div>s inside <div>s, with piles of JavaScript doing what <dialog> does for free.

So I borrowed their visual design and rebuilt it with semantic HTML and CSS using affordance classes. I want to walk you through all of the choices I’ve made and how it all comes together.


The HTML

Here’s the markup structure I use for a full-featured dialog:

<dialog id="example-dialog" class="ui/dialog" 
        aria-labelledby="example-dialog-title" 
        aria-describedby="example-dialog-desc" 
        closedby="any">
  <header>
   …

This isn’t a “real” post. This is a summary of all the things that made up my year in 2025 (almost all in a professional context). Thanks to all who were a part of it.

Writing 🔗

I published 8 articles about Ruby or software development in general this year. The first was about it. My last post of the year was a highly-nuanced take on reviewing AI PRs.

In between, I wrote about REST, flash messages, and more.

I continue sending my posts to newsletter subscribers. You can still subscribe via RSS or try to keep up wherever I post on social media.

My most-read posts are those that end up in other newsletters. This year, my writing appeared in Ruby Weekly 6 times and Short Ruby Newsletter 6 times.

I…

We are stoked to share that the Rails Core team has announced Marco Roth as the 2025 Rails Luminary.

The Rails Luminary Awards exist to celebrate those in the community who have significantly advanced Rails for the benefit of all, through contributions, gems, ideas, or knowledge-sharing, and Marco ticked all of those boxes this year.

From Rails Core member Xavier Noria:

Marco has been a prolific Open Source author for many years, and is now doing outstanding work on Herb, ReActionView, and his vision for improving the tooling and user experience around the Rails view layer. He travels the world sharing his work and knowledge at conferences and, if you have met him, you know he is as…

Rails 8.1 introduces bin/ci to standardize CI workflows based on a new domain specific language (DSL) in config/ci.rb making it easier to define, run and maintain the CI pipelines.

Understanding the DSL in config/ci.rb

The new DSL allows us to define CI steps in a structured and readable way.

  • step: Defines a single step in the workflow. The first argument is the step’s name and the remaining arguments form the command to execute.
  • success?: Returns true if all previous steps passed, allowing conditional logic.
  • failure: Displays a failure message with a description when the workflow fails. Takes two arguments: the message and a description.
CI.run do
  step "Setup", "bin/setup…

This is (mostly) parody This started as a parody of thoughtbot's recent article on the same subject, but grew from there.

While I take issue with the angle from which the author of that article attacks this problem, we ultimately do agree on the nature of the problem, so you'll find some earnest discussion in the final section.

Does your team use AI a lot? Maybe too much? Are you feeling overwhelmed by the firehose of bad code you’re having to review? I feel you. Here are some techniques and strategies I’ve adopted, as a reasonable human, which have made reviewing AI generated code feel less taxing and more productive.

What’s the same?

Before we dive into the differences between human…

Turbo’s data-turbo-confirm attribute is convenient for quick confirmation dialogs, but the native confirm() prompt it triggers looks dated and out of place. If you want a styled confirmation dialog that matches your app’s design, the traditional approach recommends a lot of JavaScript—a Stimulus controller to open and close the dialog, event listeners for keyboard handling, and coordination between the trigger and the modal.

But, recent browser updates have changed the game. Invoker Commands landed in Chrome 131 and Safari 18.4, giving us declarative dialog control. Combined with @starting-style for animations, we can now build beautiful, animated confirmation dialogs without writing any…

Fe…

December 17, 2025 Metaprogramming has always been one of Ruby’s most powerful — and most intimidating — features. While the book Metaprogramming Ruby by Paolo Perrotta is widely regarded as a classic, many developers share the same experience: it’s brilliant, but hard to truly internalize by just reading it. In a talk presented at RubyWorld … Continue reading From Reading to Mastery: Turning Metaprogramming Ruby into a Hands-On Learning Platform

As the year comes to a close, we’re thrilled to highlight our top five most-read Ruby articles of 2025:

Top 5 Ruby Blog Posts in 2025 💎

An Introduction to Solid Queue for Ruby on Rails

In part one of our two-part series, we explored Solid Queue's internals, discovered what makes it unique, and learned more about why it was created in the first place.

A Deep Dive into Solid Queue for Ruby on Rails

In the second part of our series, we dove deeper into some of Solid Queue's more advanced features.

Advanced Queries in ActiveRecord for Ruby on Rails

We got to grips with advanced ActiveRecord queries, shining a spotlight on more complex joins, custom SQL, and strategic employment of…

Ruby 4.0 will be released next week on Christmas day. This release brings a new JIT compiler, improvements to Ractors, a new mechanism to define namespaces called Ruby::Box, and a whole lot of other changes.

Although it’s a major version bump, there shouldn’t be any serious breaking changes. This version bump is to celebrate 30 years since the first public release of Ruby.

Ruby::Box

Ruby::Box is an experimental feature that brings isolated namespaces to Ruby. This can be enabled by setting the RUBY_BOX=1 environment variable. This can allow you to do things like loading two versions of a library at the same time like this:

# foo_v1.rb
class Foo
  def hello
    "Foo version 1"
  end
end

Ruby 3.4.8 has been released.

This is a routine update that includes bug fixes. Please refer to the release notes on GitHub for further details.

Release Schedule

We intend to release the latest stable Ruby version (currently Ruby 3.4) every two months following the most recent release. Ruby 3.4.9 is scheduled for February.

If a change arises that significantly affects users, a release may occur earlier than planned, and the subsequent schedule may shift accordingly.

Download

RubyGems 4.0.2 includes enhancements and Bundler 4.0.2 includes enhancements and bug fixes.

To update to the latest RubyGems you can run:

gem update --system [--pre]

To update to the latest Bundler you can run:

gem install bundler [--pre]
bundle update --bundler=4.0.2

RubyGems Release Notes

Enhancements:

  • Pass down value of BUNDLE_JOBS to RubyGems before compiling & introduce a new gem install -j flag. Pull request #9171 by Edouard-chin
  • Installs bundler 4.0.2 as a default gem.

Bundler Release Notes

Enhancements:

  • Support single quotes in mise format ruby version #9183
  • Tweak the Bundler’s “X gems now installed message”: #9194

Bug fixes:

  • Allow to show cli_help with

### Impact A cryptographic semantic binding flaw in ALTCHA libraries allows challenge payload splicing, which may enable replay attacks. The HMAC signature does not unambiguously bind challenge parameters to the nonce, allowing an attacker to reinterpret a valid proof-of-work submission with a modified expiration value. This may allow previously solved challenges to be reused beyond their intended lifetime, depending on server-side replay handling and deployment assumptions. The vulnerability primarily impacts abuse-prevention mechanisms such as rate limiting and bot mitigation. It does not directly affect data confidentiality or integrity. ### Patches This issue has been addressed by…

The one where the date was announced for Rails World 2026, where Aaron Patterson showcased the performance of object allocation in Rails 4.0, where Cookpad share how Rails help them scale, and Fizzy got API support

Joël and Aji kick off a new season by discussing the best use cases for HTTP basic auth and talking all things security.

The pair ask when and why you would use basic auth over standard HTTPS, it’s pros, cons and vulnerabilities over other forms of security, and provide some advice to help decide on what form of security you could implement on your site.

Thanks to our sponsors for this episode Judoscale - Autoscale the Right Way (check the link for your free gift!), and Scout Monitoring.

Check out these links for more information on some of the topics covered in today’s episode - Cross-Origin Resource Sharing - Cross-site request forgery (CSRF) - The Universe is Hostile to…

Arrange/Act/Assert is a name for a sequence of steps which most of your tests already perform. By recognizing this implicit pattern, and organizing your test code around it, you can make your tests easier to read and understand.

What is it?

  • Arrange: Setup objects, the database, or anything else.
  • Act: Exercise the system under test.
  • Assert: Verify the result.

Here’s a simple example:

describe "#add_tag" do
  it "adds the tag to the user" do
    tag = create(:tag)
    user = create(:user, tags: [])

    user.add_tag(tag)

    expect(user.tags).to eq([tag])
  end
end

Each of the Arrange/Act/Assert steps are separated by newlines. This makes it easy to tell them apart, so…

Enter animations are easy with @starting-style, but exit animations need transition-behavior: allow-discrete to work. Most CSS properties are continuous—opacity can be 0.5, colors can blend. But display is discrete: it’s either none or block, with no intermediate values.

The allow-discrete keyword tells the browser to apply transition timing even for discrete properties. For closing animations, the browser keeps the element visible, runs the exit transition, then flips to display: none only after the transition completes.

dialog {
  opacity: 1;
  scale: 1;

  transition:
    opacity 0.2s ease-out,
    scale 0.2s ease-out,
    overlay 0.2s ease-out allow-discrete,
    display 0.2s ease-out…

Frequently Played 🔗

I tend to listen to the same songs or albums on repeat that are evocative of how I’m feeling or what’s going on with me. Here is what I’m currently listening to over, and over, and over, and over, again.

Buckle 🔗

Just get the new album. And all the prior albums. You’re welcome.

Full Lyrics

I’m much too old for this
But I’m not over it

‘Cause I’m stupid and I’m damaged and you’re a disaster
When you walk into the room, oh, none of it matters
Oh, baby, I just buckle my resolution in tatters
‘Cause I know it won’t work, but make it ache, make it hurt
I’m not better than this, show me what I’m worth

Keep me a secret, choose someone else
I’ll still be here hanging off, I’m hanging off
The…

Painkillers 🔗

Yup, Brian Fallon again. I don’t have very varied musical tastes.

Full Lyrics

And we want love like it was a drug
Yeah, all we wanted was a little relief
And every heart I held in between
Well, they were painkillers to me
Yeah, they were painkillers to me
Come get your…

This is a guest collaboration with Stephen Margheim, creator of High Leverage Rails, a video course on building high-quality Rails applications with the power and simplicity of SQLite, HTML, and CSS.

Turbo’s data-turbo-confirm attribute is convenient for quick confirmation dialogs, but the native confirm() prompt it triggers looks dated and out of place. If you want a styled confirmation dialog that matches your app’s design, the traditional approach recommends a lot of JavaScript — a Stimulus controller to open and close the dialog, event listeners for keyboard handling, and coordination between the trigger and the modal.

But, recent browser updates have changed the game. Invoker Commands

Originally posted on the Spinel blog.

While working on rv, there’s a specific question that has come up over and over again, in many different forms. In the simplest possible form, it boils down to:

What is the difference between rv exec and rv run? Why have both?

We haven’t finished implementing either rv exec or rv run yet, but every time one or the other comes up in a conversation, everything instantly becomes more confusing.

This post will summarize the history of exec and run in Bundler, npm, Cargo, and uv. Once we have the history laid out, we can take a look at what we plan to do in rv, and you can give us your feedback.

Bundler exec

Bundler manages project-specific packages, but…

A practical guide to feature testing in Rails with Cucumber, highlighting its readability, maintainability, and team-friendly syntax through a working demo project.

In the last few days I’ve managed to finalize work on the UringMachine fiber scheduler. Beyond making sure the fiber scheduler is feature complete, that is, it implements all the different Fiber Scheduler hooks and their expected behaviour. To make sure of this, I also spent a couple of days writing test cases, not only of the fiber scheduler, but also of UM’s low-level API.

Beyond the tests, I wrote a series of benchmarks to have an idea of how UringMachine compares to other concurrency solutions:

You can consult the full results here. I’ll refrain from making overly generalized statements about what these benchmark results mean, but I think they demonstrate the promise of working…

Hi, it’s Claudio Baccigalupo. So many improvements to the Rails codebase this week!

If you are also looking to contribute, there are several documentation PRs open for community review. Oh and we also have some Rails World 2026 updates! And now, let’s get to the PR-esents 🎁

ActiveStorage immediate variants
Attachment variants gain the process: :immediately option:

has_one_attached :avatar_with_immediate do |attachable|
  attachable.variant :thumb, resize_to_limit: [4, 4], process: :immediately
end

Attachments with process: :immediately variants now eagerly analyze during validation, making metadata like image dimensions available for custom validations:

def validate_avatar_dimensions

### Summary Ruby-saml up to and including 1.12.4, there is an authentication bypass vulnerability because of an incomplete fix for CVE-2025-25292. ReXML and Nokogiri parse XML differently, the parsers can generate entirely different document structures from the same XML input. That allows an attacker to be able to execute a Signature Wrapping attack. The vulnerability does not affect the version 1.18.0. ### Impact That allows an attacker to be able to execute a Signature Wrapping attack and bypass the authentication

### Summary Ruby-saml up to and including 1.12.4, there is an authentication bypass vulnerability because of an issue at libxml2 canonicalization process used by Nokogiri for document transformation. That allows an attacker to be able to execute a Signature Wrapping attack. The vulnerability does not affect the version 1.18.0. ### Details When libxml2’s canonicalization is invoked on an invalid XML input, it may return an empty string rather than a canonicalized node. ruby-saml then proceeds to compute the DigestValue over this empty string, treating it as if canonicalization succeeded. ### Impact 1. Digest bypass: By crafting input that causes canonicalization to yield an empty…

We were gone most of the day so I told Codex CLI to migrate Better with Becky to my searls-auth gem and to commit & push regularly to a PR so I could review remotely. Just noticed that it must have looked through the git history in order to write commit messages that match my own. Seriously thought I wrote half of these before I realized as much.

Uncanny, but appreciated.

If you don't count Halo LAN parties, I probably sank more time into Knights of the Old Republic on the original Xbox than any other game. By taking the classic tabletop mechanics they were known for and theming it with a setting that didn't bore me to tears, Bioware really hooked me. I even played through every campaign quest of the middling The Old Republic MMO, which are hundreds of hours I'll never get back.

Last night, this announcement just dropped, as reported by Jordan Miller at VGC:

Announced at The Game Awards, the game is being directed by Casey Hudson, the director of the original Knights of the Old Republic game.

"Developed by Arcanaut Studios in collaboration with Lucasfilm…

Want smooth fade-in animations when your <dialog> opens? The @starting-style CSS rule defines the initial state when an element first appears—no JavaScript needed.

dialog {
  opacity: 1;
  scale: 1;
  transition: opacity 0.2s ease-out, scale 0.2s ease-out;

  @starting-style {
    opacity: 0;
    scale: 0.95;
  }
}

Without @starting-style, the browser renders the dialog immediately in its final state. With it, the browser starts from opacity: 0; scale: 0.95 and transitions to opacity: 1; scale: 1.

You can animate the backdrop too:

dialog::backdrop {
  background-color: rgb(0 0 0 / 0.5);
  transition: background-color 0.2s ease-out;

  @starting-style {
    background-color: rgb(0 0 0 /…

Joined by David Hill

Chris and Andrew kick things off with some weather whiplash and snowblower talk before introducing a new guest on the show, long-time Rubyist David Hill. They chat about fast food and favorite shows, David’s accidental path into Ruby and Rails, and various projects he’s worked on, including an AED management application. The discussion also touches on the new open-source release of Basecamp's Kanban board, Fizzy, and some innovative CSS techniques used in the project. The conversation wraps up with upcoming Ruby conferences in 2026 and how Claude's AI assistance is helping with coding tasks. Hit download now to hear more! 

Links

Building LLM-Powered Applications in Ruby: A Practical Introduction December 12, 2025 (Based on Koichi Ito’s “Ruby × LLM Ecosystem” presentation at Ruby World Conference 2025)** Large Language Models (LLMs) have rapidly evolved from experimental chatbots to foundational components of modern software. They now augment workflows in customer support, content generation, data analysis, and even development … Continue reading Building LLM-Powered Applications in Ruby: A Practical Introduction

A good website doesn’t just look nice, it works for everyone. Accessibility ensures that all users, including those with disabilities, can easily browse, understand, and interact with your site. For consultancy websites, accessibility also builds trust. It shows professionalism, attention to detail, and a genuine commitment to inclusivity.


Why Accessibility Matters

When a consultancy site is accessible, it sends a clear message: you care about people and their experience. It’s not only the right thing to do but also good for business.

Here’s why accessibility matters:

  • Wider reach. Millions of users rely on assistive technologies such as screen readers or voice navigation.
  • Better…

Rails upgrades can feel daunting due to breaking changes, gem compatibility issues and potential downtime. But staying on outdated versions is riskier. Security vulnerabilities accumulate, performance suffers, and we miss powerful features that make development easier.

With proper planning, Rails upgrades can be smooth and predictable. This five part series shares proven strategies from dozens of successful upgrades.

Why Upgrade Now?

Let’s look at the current Rails ecosystem (as of December 2025):

  • Rails 8.x: Early adoption phase (~5% of applications)
  • Rails 7.x: ~40% of active applications
  • Rails 6.x: ~35% of applications
  • Rails 5.x and older: ~20% still running

Rails 8 was…

Hi everyone!

Before the year wraps up, while everyone is planning their 2026, we wanted to share some quick information about Rails World 2026 in case that is on your conference wishlist next year (and we hope it is!).

Quick overview

  • Dates: September 23 & 24, 2026 (Wed & Thurs)
  • Location: Palmer Event Center (very central Austin)
  • CFP: open Q2/early spring 2026

Tickets

We adjust Rails World attendance to our chosen venue in each city, and since everything is bigger in Texas, that means we will have space for 1,200 attendees: the largest Rails World yet.

Tickets will be released in Q2 2026. We will have the same ticket tiers as before:

  • Corporate Tickets - pre-released; for…

#​779 — December 11, 2025

Read on the Web

Ruby Weekly

Adding Iongraph Support to ZJIT — This is a very niche item to feature, but it’s a slow week (😅) and I found it interesting, given that the ZJIT compiler will be available in Ruby 4.0 later this month. Iongraph, a tool originally built to visualize JavaScript JIT compilation, can now be used to inspect optimizations made by ZJIT too. This is a truly ‘deep in the weeds’ post, but if it encourages you to work on, or experiment with, ZJIT, fantastic!

Aiden Fox Ivey

Stuck on Rails 4.2? Ready to Upgrade Rails with FastRuby.io? — Stop postponing your…

The closedby attribute gives you declarative control over how users can dismiss a <dialog>. Want users to close by clicking outside? Set closedby="any". Need to force them through your buttons? Use closedby="none".

<!-- Light dismiss: Esc key OR clicking outside -->
<dialog id="light-dismiss-dialog" closedby="any">
  <p>Click outside or press Esc to close me.</p>
  <button type="button" commandfor="light-dismiss-dialog" command="close">
    Or close manually
  </button>
</dialog>

<!-- Platform dismiss only: Esc key, no clicking outside -->
<dialog id="platform-dismiss-dialog" closedby="closerequest">
  <p>Press Esc to close, but clicking outside won't work.</p>
  <button type="button"…

The command attribute lets you open <dialog>s declaratively—no JavaScript required. Use command="show-modal" for modal dialogs or command="show" for non-modal ones.

<!-- Modal dialog (with backdrop, traps focus) -->
<button type="button" commandfor="modal-dialog" command="show-modal">
  Open Modal
</button>

<!-- Non-modal dialog (no backdrop, doesn't trap focus) -->
<button type="button" commandfor="modeless-dialog" command="show">
  Open Dialog
</button>

<dialog id="modal-dialog">
  <p>I'm a modal dialog with a backdrop.</p>
  <button type="button" commandfor="modal-dialog" command="close">Close</button>
</dialog>

<dialog id="modeless-dialog">
  <p>I'm a non-modal dialog. You can still…

Authors: Pavel Grinchenko, Frontend Engineer, and Travis Turner, Tech EditorTopics: Design, DX, AI, Design for devtools, Vibe coding

After seeing dozens of vibe-coded projects up close, it's clear the gap between a prototype and product ready for users is wider than most expect. Eventually, progress becomes impossible without an experienced developer. We explore why that is, and I share a real-world case study to illustrate.

After seeing dozens of vibe-coded projects up close, it's clear the gap between prototype and production-ready product is wider than most think, and eventually impossible to ignore. Let's explore why that gap happens, how experienced developers are invaluable when closing…

I turned on Ring's new AI description feature for its cameras a couple weeks ago. Opened my event history for the first time since then and was kind of impressed by the honest assessment of what goes on around here.

Requestkit is inspired by Stripe’s CLI to send payloads to your app, but it instead can send (and receive!) any payload. It runs entirely on your machine. It’s a local HTTP server that captures incoming HTTP requests (webhooks) and send outbound requests (API).

Requestkit is fast, requires zero configuration and configuration can be easily shared within projects. Install it as a Ruby gem, start the server and point your webhooks to localhost:4000.

⭐ Star the project on GitHub ⭐

Tell me more!

Requestkit is a local HTTP request toolkit for development. Sounds fancy, but what can you do with it?

  • See webhook payloads: view complete headers and body data for every request in a clean…
  • Send HTTP…

[6/4] git worktrees with parallel agents in practice

This is not a comprehensive guide to Git worktrees, but I wanted to share how I'm currently using them to help you work more effectively. I also want to have a snapshot to compare against in a year, when multi-agent workflows will become more critical.

If you want to know how worktrees work fundamentally, check out [4/4] Code with LLMs in parallel. It starts with the basics of how worktrees work at the Git level and walks through the tools I don't use and why. In this post, you will see what I use almost daily and how.

"State of the Art"

I'll be a bit of a downer here because I think there is currently a mismatch between the potential parallel-agent capabilities of AI, the skill development of…

When building a Rails app, you often need to create navigation links that highlight the current page. However, Rails’ default current_page? helper only works with GET and HEAD requests. This can be problematic when dealing with forms or actions that use other HTTP methods like POST, PUT, or PATCH. This feature was introduced in this PR

The Problem

For example, if you have a page for viewing posts and another for creating posts, both share the same URL (/posts). The only difference is the HTTP method used (GET for viewing and POST for creating). With the default current_page? helper, it’s difficult to highlight the correct navigation link when a user submits a form to create a post.

The…

This year, Rails introduced a new method for ActionMailer called deliver_all_later. This feature simplifies enqueuing multiple emails for delivery through Active Job. Instead of sending each email individually, you can now enqueue a batch of emails, allowing them to be sent asynchronously when their respective jobs run.

What is deliver_all_later?

deliver_all_later enqueues many emails at once. When each job is executed, it sends the email using deliver_now. This improves performance by reducing the number of round-trips to the queue datastore, especially when dealing with a large number of emails.

How Does It Work?

To use deliver_all_later, you can pass an array of email deliveries:

ZJIT is a new just-in-time (JIT) Ruby compiler built into the reference Ruby implementation, YARV, by the same compiler group that brought you YJIT. We (Aaron Patterson, Aiden Fox Ivey, Alan Wu, Jacob Denbeaux, Kevin Menard, Max Bernstein, Maxime Chevalier-Boisvert, Randy Stauner, Stan Lo, and Takashi Kokubun) have been working on ZJIT since the beginning of this year.

In case you missed the last post, we’re building a new compiler for Ruby because we want to both raise the performance ceiling (bigger compilation unit size and SSA IR) and encourage more outside contribution (by becoming a more traditional method compiler).

It’s been a long time since we gave an official update on ZJIT.…

The new LLM world is very exciting, and I try to experiment with the new tools when I can. This includes building agentic applications, one of which is my personal accounting and invoicing tool - that I wrote about previously

As part of that effort I started experimenting with RubyLLM to have some view into items in my system. And while I have used a neat pattern for referencing objects in the application from the tool calls - the Rails Global ID system - it turned out to be quite treacherous. So, let’s have a look at where GlobalID may bite you, and examine alternatives and tweaks we can do.

What are Rails GIDs?

The Rails global IDs (“GIDs”) are string handles to a particular model in a…

Authors: Victoria Melnikova, Head of New Business, Irina Nazarova, CEO, and Travis Turner, Tech EditorTopics: Developer Community, Ruby

Here's why we scaled up our San Francisco Ruby meetups to SF Ruby Conf with 400+ Ruby engineers for three days of technical talks and startup demos.

Introduction

Composite Primary Keys (CPKs) are one of those “real world engineering” features that frameworks eventually grow into. Many enterprise databases, analytics systems, geographic indexes, and ledger tables naturally model identity using more than one attribute.

For years, Rails avoided this space and assumed a single integer column called id, and our applications were expected to adapt with Rails 8, this is finally changing. The framework now understands identity that is multi column, not just “one number per record”.

Even more interesting: Rails does this without requiring external gems, and without asking us to break conventions everywhere. The feature is still maturing, but…

Last year, we introduced case studies highlighting how companies use and build with Rails. Next up, we’re highlighting the story of Cookpad, the world’s largest recipe-sharing platform, and how Rails has powered their growth from a small startup in Japan to a global platform serving more than 100 million home cooks every month.

In this case study, you’ll read how and why Cookpad migrated from ColdFusion to Rails in 2007, and how Rails has supported their growth every day since, from their expansion to many more countries, all the way to their public offering on the Tokyo Stock Exchange.

Read the case study: The Secret Ingredient: How Rails Helps Cookpad Serve 100M+ Home Cooks

A huge…

December 10, 2025 Based on the presentation script from RubyWorld Conference 2025 This article is based on the script of the presentation “Why Now Is the Right Time for PicoRuby”, delivered by Hitoshi Hasumi (ANDPAD Inc.) at RubyWorld Conference 2025. The original session was a 30-minute conference talk, and this text adapts its core ideas, … Continue reading Why Now Is the Right Time for PicoRuby

In recent years, Markdown has become the lingua franca of plain-text files on the web. If you're a developer, you have read — and maybe even written — hundreds of Markdown documents over the course of your career.

GitHub repositories use README files written in Markdown. Stack Overflow and Reddit use it to format posts. Technical documentation, blog posts, and entire books are written in Markdown. And it's not just for humans either! AI tools such as Claude Code and Cursor use Markdown documents to improve the effectiveness of AI agents. This article you are reading is — you guessed it — written in Markdown!

Ruby on Rails, of course, has its own tooling around Markdown, and in this post,…

Exploring higher-order procedures in Ruby through a Scheme's example.

Want to avoid layout shift when you remove scrolling on popover or dialog opening? Use the scrollbar-gutter: stable CSS rule on your scroll container (likely <body>).

body {
  scrollbar-gutter: stable;

  &:has(:popover-open) {
    overflow: hidden;
  }
}

The problem: when a popover opens and you hide the scrollbar with overflow: hidden, the content shifts horizontally to fill the space where the scrollbar was.

A popover opening causes the page content to shift horizontally as the scrollbar disappears

The solution: scrollbar-gutter: stable reserves space for the scrollbar even when it’s not visible, preventing the jarring horizontal shift.

With scrollbar-gutter stable, the page content stays in place when the popover opens


All posts in this series

Want to prevent scrolling when a modal dialog is open? Use the :modal pseudo-class with body:has() to disable scrolling purely in CSS—no JavaScript needed.

body:has(dialog:modal) {
  overflow: hidden;
}

Demo:

A modal dialog opens and the page behind it cannot be scrolled

The :modal pseudo-class matches elements that are in a state where they exclude all interaction with elements outside of it until the interaction has been dismissed. This includes dialogs opened with showModal().


All posts in this series

Double-dashed IDs and the enhanced attr() CSS function allow us to bind popovertargets with their popovers without having to create distinct anchor-names.

<button popovertarget="--dropdown-example"></button>
<div id="--dropdown-example" popover></div>
[popovertarget] {
  /* Dynamically generate anchor-name from the popovertarget attribute value */
  anchor-name: attr(popovertarget type(<custom-ident>));
}

[popover] {
  /* Dynamically bind to anchor using the menu's id attribute */
  position-anchor: attr(id type(<custom-ident>));

  /* Position at bottom of anchor, aligned to left edge */
  top: anchor(bottom);
  left: anchor(left);
}

The key insight is using attr() with type(<custom-…

Have a small scroll container where you want to de-emphasize the scrollbar, like in a popover? Say hello to scrollbar-color and scrollbar-width.

::picker(select) {
  scrollbar-color: lightgray transparent;
  scrollbar-width: thin;
}

The scrollbar-color property sets the thumb and track colors (here, light gray on transparent), while scrollbar-width can be set to thin for a more subtle appearance.

Demo:

A select dropdown with a subtle, thin scrollbar


All posts in this series

Coming in the next version of Safari, and already in Chrome and Edge, you can now create <textarea>s that auto-grow with the field-sizing: content rule.

textarea {
  field-sizing: content;
  min-block-size: attr(rows rlh);
}

The min-block-size: attr(rows rlh) ensures the textarea still respects its rows attribute as a minimum height, using the rlh unit (root line height).

Demo:

A textarea that automatically grows as the user types more content


All posts in this series

<dialog>s with forms have a simple HTML-only way to implement “Cancel” buttons. In addition to POST and GET, <form>s inside of <dialog>s can make use of the dialog method. This allows the submit button to close the dialog without submitting the form to the backend.

<dialog id="example-dialog">
  <form method="POST" action="/confirmations">
    <footer>
      <button type="submit" formmethod="dialog" formnovalidate value="cancel">
        Cancel
      </button>
      <button type="submit">
        Confirm
      </button>
    </footer>
  </form>
</dialog>

The formmethod="dialog" attribute on the cancel button overrides the form’s method, closing the dialog instead of submitting. The formno…

Continuing with closing <dialog>s, in addition to formmethod="dialog" you can also implement a dialog close button in the header with an invoker command="close". Perfect way to close a dialog without a <form>.

<dialog id="example-dialog" aria-labelledby="dialog-title" aria-describedby="dialog-desc">
  <header>
    <hgroup>
      <h2 id="dialog-title">Refund payment</h2>
      <p id="dialog-desc">
        Are you sure you want to refund this payment?
        The funds will be returned to the customer's account.
      </p>
    </hgroup>
    <button
      type="button"
      commandfor="example-dialog"
      command="close"
      aria-label="Close dialog"
    >&times;</button>
 …

Ruby is a high-level language with elegant syntax. But sometimes, performance-critical tasks can be slow in pure Ruby. Writing a C extension lets us move performance-critical code into native C for speed while also tapping into existing C libraries.

Tests grow to thousands All make their claim on fixtures Frozen by demands An ancient Japanese Haiku about a common problem with software test fixtures Act 1: The problem, frozen fixtures Fixtures have a lot going for them: super fast, clearly structured, reusable across tests … That last one is also the source of a common problem in large test suites. Every time you change fixtures you ...

37 Signals launches Fizzy, Bridgetown announces 2.1 beta 1, Bundle 4.0 is released, Wired wrote a strange article about Ruby, and Errol Schmidt published their Survey Results with Ruby/Rails leaders.

The RubyMine team will be stopping by r/jetbrains on December 11 from 1–5 pm CET and doing an Ask Me Anything (AMA) thread. You’re invited to join us!

This isn’t a product launch or a marketing campaign – it’s a chance to have an open conversation about RubyMine and the challenges you face as a Ruby and Rails developer. 

How to Participate

When: December 11, 1:00–5:00 pm CET (7:00–11:00 am EST)

Where: r/jetbrains

Format:Drop your questions in the AMA thread anytime during the session.
We’ll be online responding in real time, but if you can’t make it live, you can post your questions early. This AMA is your chance to tell us what matters most, what’s working well, what’s not,…

Let's learn how to build a custom audio player with Stimulus that you can use and customize for your next application

RubyGems 4.0.1 includes enhancements, bug fixes and documentation and Bundler 4.0.1 includes performance, enhancements and bug fixes.

To update to the latest RubyGems you can run:

gem update --system [--pre]

To update to the latest Bundler you can run:

gem install bundler [--pre]
bundle update --bundler=4.0.1

RubyGems Release Notes

Enhancements:

  • Installs bundler 4.0.1 as a default gem.

Bug fixes:

  • Fixed unexpected default bundler installation. Pull request #9167 by hsbt

Documentation:

  • Update contributing docs with RGV. Pull request #9155 by eileencodes

Bundler Release Notes

Performance:

  • Increase connection pool to allow for up to 70% speed increase on bundle…

Because I'm a glutton for punishment, from time to time I'll, "rub an LLM's nose in it," when it fucks up a task. I know the chatbot can't learn from this, and I know I'm just wasting 8¢ of some idiot investor's money, but I do it anyway.

Today, I asked:

in photos app for mac, i have an album. i want to export everything int the album into a directory that is organized yyyy/mm/dd subdirectories -- how?

ChatGPT 5.1 (Auto) replied with a long, mostly useless screed that started with:

macOS Finder has a hidden but fully working "Create folders from date" automation via Quick Actions or Shortcuts.

Immediately recognizing that statement as bullshit of the too-good-to-be-true variety, I pushed…

More than Metrics: A Marketing Coordinator's Look at 2025

In marketing, the metrics guide us, but connection is what gives the work its purpose.

Continue Reading

This post explores Rails’s swappable migration backend, a little-known feature that lets applications customize how migrations run. At Shopify, we relied on monkey patches and a brittle SQL parser to make Rails migrations work with our Schema Migrations Service. We developed the swappable backend feature to more simply adapt Rails’s migration runner to our needs. We’ll cover why and how we built this, and how Shopify uses it to power database migrations at scale.


At Shopify, we run hundreds of database migrations across many Rails applications every week. Each migration needs to be vetted for safety and executed in a way that doesn’t cause downtime for our merchants. For years, we relied…

Tools on a wall

Introduction

Large Language Models (LLMs) have gained significant traction recently due to their flexibility, ease of setup, and continuous improvement in performance and cost-efficiency. Meanwhile, other powerful machine learning algorithms have been established for decades. This article investigates whether these long-standing algorithms remain relevant for ranking tasks or if LLMs can effectively replace them.

Background

At Gusto, we offer a range of bookkeeping integrations, allowing companies to smoothly export data from Gusto to accounting platforms. This process requires mapping internal Gusto categories to external bookkeeping accounts. Accountants typically spend a considerable amount…

Back in the mists of time, I used a tool called rvm. It was more than just a Ruby version manager, it was also a gemset manager: instead of using bundle exec or a binstub, you could just type a command and it would “work” because every version+gemset was a pristine environment. Cool in a way, but also very complicated.

I eventually migrated to the simpler rbenv and have used that for years now. It only manages Ruby versions and expects you to make use of Bundler to keep gems and executables in line. Y’know. Modern Ruby.

But what if you could use something even more modern than rbenv? Enter rv.

Inspired by uv in the Python ecosystem, rv aims to become your singular solution for total…

RubyMine 2025.3 is out!

This blog post briefly goes over the highlights of the latest release. For a detailed description, check out our What’s New page. 

You can get the new build from our website or via the free Toolbox App.

AI Assistant

Multi-agent experience: Junie and Claude Agent

With the addition of Claude Agent, the first third-party AI agent fully integrated into JetBrains IDEs, your development workflow becomes more flexible and powerful.

Both Claude Agent and Junie are now accessible from the same chat interface, allowing you to seamlessly switch between them and get the right kind of assistance for every task, whether it’s code generation, debugging, or…

Hotwire Weekly Logo

Welcome to Hotwire Weekly!

Welcome to another, issue of Hotwire Weekly! Happy reading! 🚀✨


📚 Articles, Tutorials, and Videos

Vanilla CSS is all you need - Rob Zolkos makes the case for skipping heavy CSS frameworks and leaning on modern, plain CSS instead, with examples from Fizzy.

DriftingRuby: Cool Things in Fizzy - David Kimura published a new episode that highlights neat Ruby- and Rails-related tricks in Fizzy. It walks through features and patterns, showing how you can use it to clean up code and improve maintainability in Rails apps.

37 Signals Fizzy Kanban board - Similarly, Brad Gessler shared a video-walkthrough of the Fizzy source code.

Instant Drag&Drop in Fizzy - Jorge Manrubia

December 8, 2025 The RubyWorld Conference 2025, held in Matsue, Japan, showcased an unexpected star of the ecosystem: Ruby running on microcontrollers. While the event traditionally focuses on Ruby in web, enterprise, or academic settings, this year a significant amount of attention shifted toward embedded systems, thanks to PicoRuby and the community project mruby Girls. … Continue reading RubyWorld Conference 2025: PicoRuby, mruby Girls, and the Future of Embedded Ruby

Dion Lim wrote a pretty good angle on what the market correction will actually do:

The first web cycle burned through dot-com exuberance and left behind Google, Amazon, eBay, and PayPal: the hardy survivors of Web 1.0. The next cycle, driven by social and mobile, burned again in 2008–2009, clearing the underbrush for Facebook, Airbnb, Uber, and the offspring of Y Combinator. Both fires followed the same pattern: excessive growth, sudden correction, then renaissance.

Now, with AI, we are once again surrounded by dry brush.

I think in one of our discussions before our Hot Fix episode, Scott Werner and I used the same analogy—that a recessionary fire will be necessary to clear the overgrowth…

In this episode, we look deploying Fizzy to a server and look at some of the notable practices found in the code.

  • My goal for this week was to rewrite our new landing page copy in a friendlier, more conversational tone. And I got half of it done! One more solid session should do it. Max has been continuing to iterate on the design for these pages, and I think we have a visual approach that will work a treat with this kind of voice.

    Jojo has also been chipping away at the site, recently fixing most of our 404s. Having everything in one place is going to make this kind of maintenance so much easier in the future!

  • Website writing wasn’t the only writing I did this week. I also drafted up a submission for the gem fellowship, which I’ll submit this coming week. Regardless of the outcome for my…

Direct link to podcast audio file

I'm experiencing what breathing out of my nose properly feels like for the first time. Everything is new and wondrous and I've never felt so optimistic. This sensation lasted for two days and now I'm used to it and existence is once again pain.

Share your existential musings at podcast@searls.co and I'll nod and sigh along. I might even nod and sigh performatively for you on the show!

Important ground covered in this episode:

I’m currently doing grant work for the Japanese Ruby Association on UringMachine, a new Ruby gem that provides a low-level API for working with io_uring. As part of my work I’ll be providing weekly updates on this website. Here’s what I did this week:

  • Last week I wrote about the work I did under the guidance of Samuel Williams to improve the behavior of fiber schedulers when forking. After some discussing the issues around forking with Samuel, we decided that the best course of action would be to remove the fiber scheduler after a fork. Samuel did work around cleaning up schedulers in threads that terminate on fork, and I submitted a PR for removing the scheduler from the active…

Hi, it’s Emmanuel Hayford. Here’s a look at the highlights from this week’s updates to the Rails codebase.

Add schematized json for has_json
Provides a schema-enforced access object for a JSON attribute. This allows you to assign values directly from the UI as strings, and still have them set with the correct JSON type in the database.

Only the three basic JSON types are supported: boolean, integer, and string. No nesting either. These types can either be set by referring to them by their symbol or by setting a default value. Default values are set when a new model is instantiated and on before_save (if defined).

Examples:

class Account < ApplicationRecord
  has_json :settings, restrict…

Snow was falling hard across the arctic hillside. The wind was biting. No trees offered shelter. Our hero was laying in the snow, barely conscious. His gear was strewn about him. His memories were a blur. He had known many names, but he knew not what they called him in this realm. This realm felt unfamiliar.

He struggled to his feet. The wind whipped snow into his eyes as he attempted to orient himself. He made out a faint glow in the distance and began to gather his gear.

Among his usual equipment were some items that seemed out of place. The first was a box made of a smooth, white, metallic material. It seemed to be designed to collect something, but he did not know what.

def…

Docker Disasters and Dev Container Journeys

Andrew kicks off at 8 a.m. with six Docker containers running, and he and Chris dive into what modern Rails development looks like inside dev containers—covering Rails’ own images and features, using Mise and Playwright instead of Selenium, and why OrbStack has replaced Docker Desktop on their Macs. They talk through the trade-offs of running services in containers, the quirks of Kamal’s new local registry, and how Chris is turning all of this into a practical SaaS building series that shows real-world deployment and scaling with tools like JudoScale. Along the way, they weave in life updates about new babies, daycare costs, and even the power needs of AI data centers and nuclear energy. …

A short blog on some tips to cleanly pluralize and translate content in Rails.

Authors: Irina Nazarova, CEO, Vladimir Dementyev, Principal Backend Engineer, and Travis Turner, Tech EditorTopics: DX, AI, Design for devtools

We've experimented putting the essence of a Martian engineer into AGENTS.md. Learn the story, then try it on your next AI-assisted project!

Founders, designers, PMs, marketers—technical at different levels, but not engineers—use code generation tools heavily now. It feels liberating. It’s also incredibly addictive. But the reality check begins when an engineer opens your repo and (despite their best effort to make things work) must throw away everything you vibe coded and rewrite it from scratch. If you want to prevent that, this post is for you. This…

ZJIT adds support for Iongraph, which offers a web-based, pass-by-pass viewer with a stable layout, better navigation, and quality-of-life features like labeled backedges and clickable operands.

Prelude

I’m an intern on the ZJIT team for the fall term. I also have a rather bad habit of being chronically on lobste.rs.

While idly browsing, I spotted an article by Ben Visness titled Who needs Graphviz when you can build it yourself?, which covers his work on creating a novel graph viewer called Iongraph.

Iongraph used to visualize an IR graph for the SpiderMonkey JIT inside Firefox.

Immediately, I was intrigued. I like looking at new technology and I wondered what it might be like to integrate the work done in Iongraph with ZJIT, getting all sorts of novel and…

#​778 — December 4, 2025

Read on the Web

Ruby Weekly

RubyGems and Bundler 4.0 Released — If you want to get ahead of any potential issues the Ruby 4.0 upgrade may surface, the early release of RubyGems 4.0 and Bundler 4.0 could help you get started. There's many tweaks and minor improvements, like -j being set by default to speed up compilation of native extensions, cache_all true by default, and the ability to specify custom lockfile locations. There are some potentially breaking changes too, though, like the removal of support for multiple global sources in Gemfiles.

Hiroshi Shibata

💡 If sifting through a…

i know Des Revol, and know them to be an incredibly kind, solid, reliable person.

For real he’s facing federal charges and threat of deportation because of subversive political pamphlets found in his trunk.

Des was not at the Prairieland demonstration. Instead, on July 6, after receiving a phone call from his wife in jail (one of the initial ten), Des was followed by Federal Bureau of Investigation (“FBI”) agents in Denton, Texas. They pretextually pulled him over due to a minor traffic violation and quickly arrested him at gunpoint. He was later charged with alleged “evidence tampering and obstruction of justice” based on a box of political pamphlets that he purportedly moved…

Picture this: you find a charming old board game at a garage sale, bring it home, gather some friends—and snap. The 50-year-old plastic components break instantly. You search the web for help to replace this fun and unique game mechanic but there’s nothing to be found. So naturally, you roll up your sleeves and build your own mobile version. No one else does this? Just me? Well, in case you ever find yourself in a similar boat, I figured I would walk you through what I did when building my own mobile integration to the 1973 Parker Brothers classic Billionare.

As I said, right when I went to try out this cool "new" board game for the first time, the plastic ends of the Analyzer

Web application monitoring is the nervous system for our software—continuously listening, collecting signals, and analyzing them to catch problems before they become outages. A one-hour outage can cost millions. Amazon lost an estimated USD 34 million in 2021, while Meta lost close to USD 100 million in a similar incident. Effective monitoring moves our team from reactive firefighting to proactive fire prevention.

The Four Pillars of Telemetry

Modern applications are complex, distributed systems with dozens of moving parts. Without visibility into what’s happening inside, we’re flying blind. Monitoring solves this by collecting four types of telemetry data:

1. Metrics: The Vital Signs

M…

Custom elements are one of those web platform features that sound complicated but turn out to be surprisingly simple. If you have used Hotwire in Rails, you have already used them. Both <turbo-frame> and <turbo-stream> are custom elements. They are just HTML tags with JavaScript behavior attached.

This article walks through what custom elements are, how they compare to Stimulus controllers and how to build them yourself! Starting with a simple counter and ending with an optimistic form that updates instantly without waiting for the server. 🤯

The code is available on GitHub.

What are custom elements?

Custom elements let you define your own HTML tags with custom behavior. They fall under…

Ever since JRuby 10 upgraded to Java 21, I’ve been re-learning Java with all the excellent language enhancements of the past decade. One of my favorites has to be the instanceof pattern matching features added in Java 16. Today I also realized I can use an instanceof pattern to null-check and assign a variable at the same time.

Using instanceof to null-check

When checking if a value in Java is instanceof some type, we can get a false result in two cases:

  • The value is an instance of a type not equal to or descended from the specified type.
  • The value is null.

This second property turns instanceof into a weird sort of null-check when applied to a variable or method that matches the i…

At OmbuLabs, open source has always been at the core of our values. This year, for Hacktoberfest 2025, our team took the opportunity to give back to the communities that power our daily work, from Ruby developers tackling technical debt to those building the next generation of AI tools. Throughout October, we dedicated focused internal time to open source contributions. Our goal was twofold:

  1. Strengthen and maintain the tools that power our work at FastRuby.io, helping teams manage technical debt and improve code quality.
  2. Advance Ruby’s presence in artificial intelligence, contributing to libraries and frameworks that integrate Ruby with modern AI technologies. By aligning…

Packages, especially in node/JavaScript land, have been used to modularize software for some time now. The monorepo as a structure that defines a flurry of packages under a common namespace and released with the same version number at the same time has become somewhat popular in the last few years, with popular packages such as Babel leaning heavily into that.

We have, if a bit crudely, supported these monorepo-packages for quite some time. In the beginning via Greenkeeper’s monorepo definitions, then, after Greenkeeper became part of Snyk and the list was no longer maintained, with a private list that we updated whenever a client mentioned something missing.

We’ve decided to finally…

December 3, 2025 By Germán Silva Bindings are one of the most underrated yet critical pieces of the Ruby ecosystem. They are the bridges that connect Ruby to native libraries, databases, protocols, and even hardware. Bring Your Next Project to Life with High-Quality Development Don’t miss the opportunity to take your project to the next … Continue reading The Ruby Bindings Every Rails Developer Should Know

Introduction

Ruby 3.1 introduced Fiber::Scheduler#io_select, making IO.select work seamlessly with fiber-based concurrency. Before diving in, let’s clarify some key concepts.

What’s a Fiber?

A fiber is a lightweight, pausable unit of execution in Ruby. Unlike threads, fibers don’t run in parallel—they cooperatively yield control to each other, making them predictable and efficient for I/O-bound tasks.

fiber = Fiber.new do
  puts "Starting"
  Fiber.yield  # Pause here
  puts "Resuming"
end

fiber.resume  # => "Starting"
fiber.resume  # => "Resuming"

What’s a Scheduler?

A scheduler manages when fibers run. When a fiber performs I/O (like reading from a socket), the scheduler pauses it…

We introduced breaking changes in RubyGems/Bundler 4 in order to improve usability, security, and maintainability of the tool. This document describes the changes that you will find when upgrading to RubyGems 4 and Bundler 4, and how to prepare for them while still using Bundler 2.7.

RubyGems 4: CLI behavior changes

Removed gem query command

Please use gem search or gem list instead.

Completely removed gem install --default feature

The --default option was confusing for RubyGems users and caused broken installs.

This was an unfinished feature originally intended to install gems directly into the Ruby standard library location, but it only generated executables without properly copying…

RubyGems 4.0.0 includes features, performance, enhancements, bug fixes, security, breaking changes, deprecations and documentation and Bundler 4.0.0 includes features, performance, enhancements, bug fixes, security, breaking changes and documentation.

To update to the latest RubyGems you can run:

gem update --system [--pre]

To update to the latest Bundler you can run:

gem install bundler [--pre]
bundle update --bundler=4.0.0

RubyGems Release Notes

Features:

  • Undeprecate Gem::Version.new(nil). Pull request #9086 by tenderlove
  • Add pattern matching support to Gem::NameTuple. Pull request #9064 by baweaver
  • Add pattern matching support to Gem::Platform. Pull request #9062 by…

Performance:

  • Add MAKEFLAGS=-j by default before compiling. Pull request #9131 by Edouard-chin
  • Remove some memoization. Pull request #9017

On November 27th, 2025, the la_plata.rb community came together at Calle Uno for what became the first and last meetup of the year in the city. More than 30 Ruby developers gathered together to share knowledge, experiences, and drinks.

The meetup was made possible thanks to the support of RubyCentral, GitHub, SINAPTIA, and Unagi. Many thanks to our sponsors; this wouldn’t have been possible without them.

Observability en la era de AI

The first talk was presented by Patricio Mac Adden from SINAPTIA, who shared his team’s journey combining observability tools with LLMs to tackle real-world Rails application problems. With an upfront disclaimer that this wasn’t “the definitive solution” but…

It's the most wonderful time of the year - Christmas Advent of Code time! Advent of Code is an Advent Calendar style series of programming puzzles put out each year, starting on December 1st leading up to Christmas. The puzzles are super festive and ramp up in difficulty over the course of the month. Programmers of every level can participate, and in researching some of the more difficult problems you'll probably learn something cool! It's a great way to finish out the year.

I've been taking part in Advent of Code since 2019 (I've never completed a full year - and that's ok! You can participate for as long as it's fun and have the time) and have tried solving in multiple different…

Expose your local Rails app to the internet with a secure, stable, and free Cloudflare Tunnel — perfect for webhooks, client demos, and remote testing.

The one with BFCM deals, where Xavier Noria and Kevin Newton shared insights about how constants work in Ruby and where Alessandro Rodi introduced DevToolsController for Rails.

This blog series is dedicated to celebrating our Black, Latinx, and Women Engineers who are making an impact in the lives of our Gusties and Gustomers (Gusto customers) every day.

Today, we’re spotlighting Masha (Maria) Gorkovenko, who has been with Gusto for 1 year, working on enabling lower-cost health insurance offerings and creating an Agentic Benefits Advisor for the Benefits team.

Kevin: How did you join Gusto?

Maria: I joined Gusto last October, so it’s been almost exactly a year now. Before that, I was a founder at my own startup where we built AI agents. Joining Gusto felt like a natural continuation of that work — I’m now part of the Benefits team, focusing on our Generative…

Kevi…