MapView: Static maps for Rails. No JS. No frontend. Just Ruby. April 7, 2026 From the creator of ruby-libgd and libgd-gis comes native Rails integration Many of you already know ruby-libgd – the gem that brings GD graphics power to Ruby. Many of you already know libgd-gis – the GIS rendering layer built on top … Continue reading MapView: Static maps for Rails. No JS. No frontend. Just Ruby.
4.0.10 Released
RubyGems 4.0.10 includes enhancements and bug fixes and Bundler 4.0.10 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.10
RubyGems Release Notes
Enhancements:
- Ignore warnings with spec different platforms. Pull request #8508 by hsbt
- Better algorithm for sorting gem version. Pull request #9421 by Edouard-chin
- Update SPDX license list as of 2026-02-20. Pull request #9434 by hsbt
- Installs bundler 4.0.10 as a default gem.
Bug fixes:
- Register native extension files in default spec map. Pull request #9431 by hsbt …
Spoken Latin
Normally this is a programming blog, but here’s something different.
My justification is April Cools’ Club, which henceforth will allow me once a year to write about something completely random (something I’ve done before without knowing it was excusable).
My inspiration was the Spring 2026 Lobsters blog carnival, where participants are provoked to defend the superiority of our favorite language. I accept the challenge, and I step forward to defend the honor of…
Latin.
…One new skill in this release: rails-upgrade.
Why I built this
Seeing the skills for upgrading a Rails app released in the last months with the one from OmbuLabs/FastRuby.io being released last week:
-
OmbuLabs/FastRuby.io: detection patterns, gem compatibility data, upgrade methodology
-
maquina-app/rails-upgrade-skill by Mario Alberto Chávez Cárdenas: breaking changes reference tables, deprecation timeline
I got thinking that maybe it is time for superpowers-rusuperpowers-rubyby to have such a skill.
The workflow
The skill runs a six-step process, but three of those steps are hard gates: the agent cannot proceed past them unless a condition is met.
The first gate is a green test suite.…
When you build a product that uses LLMs and prompts, security becomes a specific kind of hard problem.
Simon Willison described the core risk well in The Lethal Trifecta. When three things combine in a system: access to private data, exposure to untrusted content, and the ability to communicate externally, the situation becomes dangerous.
The reason is structural: LLMs follow instructions in content. That is what makes them useful. It is also what makes them exploitable. An attacker embeds instructions in a document, an email, a webpage, and the model may execute them.
Prompt injection is the number one vulnerability in LLM applications according to OWASP's Top 10 for LLMs. And unlike SQL…
I’m one of the operators of rubygems.org. Here’s what’s been happening over the past week, and a temporary change we’re making as a result.
For the past seven days, rubygems.org has been under sustained bot traffic from many different sources scraping data from every published gem. The volume has been large enough to force the site offline while we respond. The bots are deliberately bypassing the Fastly cache, hitting our origin servers directly.
The primary target has been our language locale pages, the translated versions of rubygems.org. Unfortunately, the locale system wasn’t designed to cache easily through a CDN. To protect site stability, we’re temporarily disabling language…
Your agent’s context window is the most precious resource it has. The more you stuff into it, the worse your agent performs.
Researchers call it context rot: the more tokens in the window, the harder it becomes for the model to follow instructions, retrieve information, and stay on task. Chroma tested 18 frontier models and found that accuracy drops up to 30% when you go from a focused 300-token input to 113k tokens of conversation history, with the task held constant. The model essentially became dumber.
This holds true regardless of how big the window is, yet most agent setups treat the context window like a junk drawer.
“Just toss it in there, the LLM will figure it out!”
MCP: the…

Learn what's new in the world of slow tests and how TestProf continues to help Rails teams to keep CI build times under control.
Behind every release of TestProf is a story about battling a real-world Rails application's test suite slowness. This time, we've picked standout cases from Evil Martians' recent CI performance gig at Whop. Learn what we used to identify and fix them and how this experience shaped TestProf v1.6.0.
JRuby 10.0.5.0 Released
The JRuby community is pleased to announce the release of JRuby 10.0.5.0.
- Homepage: https://www.jruby.org/
- Download: https://www.jruby.org/download
JRuby 10.0.5.x targets Ruby 3.4 compatibility.
Thank you to our contributors this release, you help keep JRuby moving forward! @evaniainbrooks, @kares, @chadlwilson, #jimtng
Compatibility
- Fixed: Two bugs in the JIT compiler that broke certain super calls and defined_method yields. (#8944, #8946, #9310, #9349)
- Fixed: Fiber#raise left the fiber in an resumable state by not correctly transfering control. (#9297, #9356)
- Fixed: Connecting a socket using nonblocking operations failed to complete the establishment of the connection.…
JVM Integration
- Java 26 is officially supported. (#9332)
Pl…
Dear Heroku,
As friends, long time marketplace-partners, supporters, and customers, we here at Judoscale — along with so many others from the developer community — are a bit confused about what’s going on over there in San Francisco. Frustrations aside, we’re having a hard time figuring out what to think about this whole ‘Heroku thing’.
First came the blog post on February 6th that, sort of out of nowhere, announced that:
Heroku is transitioning to a sustaining engineering model focused on stability, security, reliability, and support… with an emphasis on maintaining quality and operational excellence rather than introducing new features…
Enterprise Account contracts will no…
Which, full disclosure, sounds an awful lot like a product going into “Maintenance Mode”, even if that specific phrase isn’t said. Speaking of specific phrases, what exactly is a…
This Week in Rails: Faster Logs, Reliable Parallel Tests, and Key Deprecations April 5, 2026 A new batch of improvements has landed in the Rails codebase this week, focusing on performance refinements, testing reliability, and cleaning up legacy configuration options. Here is what you need to know. The Headline Change: No More Slow SQL Logs … Continue reading This Week in Rails: Faster Logs, Reliable Parallel Tests, and Key Deprecations
Hi, it’s Vipul. Let’s explore this week’s changes in the Rails codebase.
Remove fast_string_to_time workaround in ActiveModel::Type::Helpers::TimeValue
Ruby 3.2.0 had a bug where Time.new(..., in: "UTC") could return an invalid Time object.
With the minimum supported Ruby now at 3.3.1, the runtime probe and workaround are dead code and have been removed.
Add prepend: true option to ActiveSupport::Notifications.subscribe
A new prepend: true option on ActiveSupport::Notifications.subscribe ensures a subscriber runs before all others
enabling payload mutation before any downstream handler sees it.
ActiveSupport::Cache add a fast path for string keys
Since most cache keys are already…
Easter Eggs
Continuations 2026/14: Taiwan Edition
Welcome to a special 🇹🇼 Taiwan Edition of my weeknotes. We’ll be spending the next couple of weeks here on a family holiday. Right now I am tired (after 24+ hours of travel) but happy and full of delicious food. I aim to keep the weeknotes coming, but I’ll try to keep the next few brief.
This week I finished my rewrite of Hanami Mailer! It’s all merged now and ready for testing as a standalone system. The next step here is to get the integration with full Hanami apps happening.
We had a good question come into our chat about how Hanami CLI calls the Postgres CLI tools for its
dbcommands (tl;dr, nothing special, you just need them on your$PATH). It eventually got onto the topic of how…
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.
Witch Dance 🔗
Grief, perseverance, the search for community, the desire for answers.
And I met every monster from the bar to Broadway
And all their violent offers, I just turn them away
And your threats and your promises, they don’t scare me
After all, there’s nobody more monstrous than me
Opening of The Land Of Hope And Dreams American Tour 🔗
I finally watched Deliver Me From Nowhere. My recommendation? Read the book. Or, better, listen to Nebraska.
The mighty E Street…
Ruby is a programming language created for the happiness of the programmer, but apparently this happiness did not account for the installation process of the language itself. If you go to the official language page, you will find a list of solutions to install and manage Ruby versions. But almost all of them have one problem: you have to compile the version locally, and the time it takes will depend on how fast your CPU is.
Now that is changing; a new tool called rv has emerged. It is described as “an extremely fast way to manage your Ruby versions and gems”. In this post, I want to explain a bit how it works, why it is so fast compared to previous solutions, how you can use it to install…
Memcached Mayhem
On this episode, Chris, Andrew, and David bounce from Ruby and Rails security updates into the messy realities of caching, UI architecture, and browser support. They break down the latest Zlib-related Ruby CVE, Dalli updates, Rails security and bugfix releases, and what maintenance windows mean in practice. Then, they swap stories about Redis, Memcached, observations about GitHub’s reliability amid massive Claude attributed code activity, and the kinds of performance problems that only show up at scale. The episode closes with a thoughtful Rails frontend discussion covering nested layouts, active sidebar links, CSS-powered empty states, pagination behavior, popovers, anchor positioning, and…
Last week, three members of Ruby Central’s board published a new statement about RubyGems and Bundler, and this week they published an incident report on the events last year. The first statement reports that Ruby Central has now completed a third audit of RubyGems.org’s infrastructure: first by the sole remaining RubyGems.org maintainer, the second by Cloud Security Partners, and the third by Hogan Lovells.
In all three cases, Ruby Central found no evidence of compromised end user data, accounts, gems, or infrastructure availability. I hope this can conclusively put to rest the idea that I have any remaining access to the RubyGems.org production systems, or that I caused any harm to the…
I also appreciate that Ruby Central is taking its share…
#794 — April 2, 2026
Ruby Weekly
The 'RubyGems Fracture' Incident Report — A postmortem of the Ruby Central vs Bundler story in late 2025 which resulted in the Ruby core team taking stewardship of RubyGems and Bundler. The timeline of events is laid out in detail, but it’s unlikely to resolve the matter entirely (as demonstrated in this Reddit comment by Mike Perham).
Richard Schneeman (Ruby Central)
💡 The Register also has a good independent take on this update factoring in some of the responses to it.
How a Solo SaaS Founder Stopped Worrying About Rails Maintenance — "FastRuby.io is…
This article is taken from the book JavaScript for Rails Developers (use ONE-YEAR-OLD to get 25% discount; valid until 2025-04-09 🥳). It is a book I published about a year ago. Over that period, many hundreds bought the book. It is written for Ruby/Rails developers to make JavaScript your 2nd favourite language.
I always get a little excited when I see a good refactoring happen. So I want to share this article; it is one of the last chapters where I go over an exisintg part of the code that is created in the book to refactor it with the goal to make it:
- more readable;
- easier to understand at a glance.
This is the current code it started with:
import { Annotation, Transaction } from "@code…Basic role management
Believe it or not, I don’t only work on or write about SQLite, and today I want to share a simple pattern for role management in Rails inspired by the rolify gem. I have been using this setup in the Rails app I am currently working on, and it has been a lovely experience. I’ve also had to evolve the pattern a bit recently, so I thought now was a great time to share the current state of things. Let’s jump into it!
The pattern works with 3 core models and then any number of related models. The core models are (you guessed it) User, Role, and UserRole. The User model represents, well, a user of your application. The Role model is a role that a user can have. The UserRole model is the join…
N+1 Driven Development
htmx Configuration
Often, you’ll want to customize the default htmx configuration. There are a couple ways you can do this:
-
Globally.
-
Per page.
We’ll discuss each including how you can make short order of these configuration changes in your Ruby applications. For the purposes of this discussion, we’ll use Hanami as our web application but what you see here can be applied to your specific web stack.
With the above in mind, let’s get started by first setting up our htmx provider.
Provider
As documented in Hanami Containers, the best way to have access to the HTMX gem is to implement a corresponding provider. Here’s…
…We analyzed 1,140 devtools funding rounds—here's who's writing checks and why

We analyzed 1,140 early-stage funding rounds in developer tools, cybersecurity, and infrastructure from January 2025 through March 2026. Here are the top VCs and investors writing checks, the metrics that got companies funded, and the exact person to email based on what you're building.
In other places, founder dreams might include sports cars or fancy watches, but here in San Francisco, every devtools founder wants one thing: to be on a bus. Specifically, their logo painted on a Muni line crossing Market Street. If you're on a Muni, you've made it, like Modal, Blacksmith, Posthog, Hex. Another way to…
Rails apps have layers but no modules
You can have 200 models and zero modules. That’s the problem with typical Rails conventions. Rails supports layers - models, views, controllers. But layers are not modules. Within one layer - especially models - usually all is mixed together. There are no boundaries.
Order.first.user.invoices.last.line_items
Such code is not so uncommon. It crosses 4 business boundaries. In just 1 line of code. All thanks to associations.
The problem with associations
One of the first thing we teach in Rails is associations.
class Order < ApplicationRecord
belongs_to :user
end
It’s very readable, feels right. Allows us to call it like this:
Order.first.user
Then…
When Search Breaks Everything: Lessons from a Client's Unexpected App Outage
Judoscale ‘On Tour’ Series
- “The Friction Model” & Heroku (This page!)
- Render (Coming soon…)
- Railway (Coming soon…)
- Fly (Coming soon…)
- Northflank (Coming soon…)
- Digital Ocean (Coming soon…)
- Amazon ECS Fargate (Coming soon…)
Thus we begin our tour! As we mentioned in our last post, we’re going to take our production app on a hosting tour to fully experience what each option in today’s hosting marketplace looks like, feels like, and runs like. But before we do any of that, we need a baseline and a strategy.
Judoscale has been on Heroku since its origins ten years ago. Adam, Judoscale’s founder, has been using Heroku since it was a first-days startup! All that to say,…
Last year, I announced plans to rewrite this blog in Ruby on Rails. It was hosted on Ghost for all these years (which is built with Node.js), and the idea was to rebuild it from scratch in Rails and write about the process as I went along. I even published a few posts as I started development.
However, as you may have noticed, I haven't published consistently for the past six to eight months. What's more, for the last two months, I haven't even written a single post.
Part of the reason is AI, and the proliferation of AI-generated writing everywhere which completely killed my motivation to write. Why spend hours and even days writing a detailed technical blog post when Claude or…
This is a copy of the canonical report I published on RubyCentral’s site. I recommend reading there for the most updated copy. This document attempts to give closure to the Ruby community about the events that led to the incident, September 10-18, 2025, which I’ve named “RubyGems Fracture.”
Preamble
I joined Ruby Central’s Open Source Committee on October 22nd, 2025, after the GitHub access changes. I was adamant internally and externally from day one about performing a retrospective to try to wrap my head around the full, true picture of what happened and why.
In the pursuit of this task, I’ve spent 20+ hours interviewing and chasing up leads, easily quadrupling that time…
RubyGems Fracture Incident Report
By: Richard Schneeman
This document attempts to give closure to the Ruby community about the events that led to the incident, September 10-18, 2025, which I’ve named “RubyGems Fracture.”
Preamble
I joined Ruby Central’s Open Source Committee on October 22nd, 2025, after the GitHub access changes. I was adamant internally and externally from day one about performing a retrospective to try to wrap my head around the full, true picture of what happened and why.
In the pursuit of this task, I’ve spent 20+ hours interviewing and chasing up leads, easily quadrupling that time spent reviewing other artifacts such as chats and raw GitHub access logs. For any fact learned verbally, I’ve…
A new way to decouple code since Rails 8.1.

There are these moments where you feel stuck between the devil and the deep blue sea. Two possible solutions, neither quite up to the job.
Let’s start with a simple example that illustrates what we’re competing against. You are implementing an e-commerce solution that sells digital products. After a purchase is placed, a few things need to happen: send a confirmation email, track the event in your analytics, and ping your team on Slack. Your first pass looks something like this:
def create
@order = Order.create!(order_params)
OrderMailer.confirmation(@order).deliver_later
Ahoy::Event.create!(name: "order.created", properties: {…Configuring monitors in Hyprland means writing monitor= lines by hand. A 4K display at 1.33x scale is effectively 2880x1620 pixels, so the monitor next to it needs to start at x=2880. Vertically centering a 1080p panel against it means doing division in your head to get the y-offset right. You reload, you’re off by 40 pixels, you edit, you reload again. There’s no visual feedback until after you’ve committed to a config.
Then it gets worse. You unplug your laptop, go to a conference, plug into a projector, and you’re back to editing config files backstage before your talk. You come home, dock the laptop, and the layout is wrong again.
I looked at what was available. The closest to what I…
Haggis Ruby returns to Glasgow on April 23-24, and thoughtbot will be there.
Rob Whittaker and Mina Slater are attending, and Aji Slater is speaking. Their talk is about playfulness in exploration when tackling novel challenges. What is the challenge in this case? Using Ruby for procedural generation of an endless haunted house.
Haggis Ruby is one of the smaller Ruby conferences, and that’s part of what makes it good. The conversations are better when the room is smaller. If you’re in or around Glasgow in late April, it’s worth the trip.
We’re looking forward to it. If you’re going, find us.
If you enjoyed this post, you might also like:
I joined Jared again on the Dead Code Podcast to go a bit deeper on my post, The Death of a Software Craftsman. The outlook is kinda bleak, but plenty of digs at agile software practices :)

NestJS is code-first by default meaning decorators describe your API, and the spec is generated from code. But decorators don't enforce anything at compile time. This post shows how to flip the flow to generate controller method types from an OpenAPI spec and let TypeScript catch contract drift before reaching production.
NestJS defaults to code-first: you write controllers, decorate them, and generate the spec from code. The spec is a byproduct. But those decorators are runtime metadata, so TypeScript doesn't check them against your actual return types. This article flips the flow. We…
CVE-2026-33946 (mcp): MCP Ruby SDK - Insufficient Session Binding Allows SSE Stream Hijacking via Session ID Replay
CVE-2026-34060 (ruby-lsp): Ruby LSP has arbitrary code execution through branch setting
Welcome to Hotwire Weekly!
Welcome to another issue of Hotwire Weekly! Happy reading! 🚀✨
📚 Articles, Tutorials, and Videos
Add to Calendar Bridge Component for Hotwire Native - Mike Dalton walks through building a Hotwire Native bridge component that triggers native calendar APIs from a Rails view, using iOS EventKit to present an EKEventEditViewController and an Android Intent to open the device calendar app.
Build custom emojis with Stimulus - Rails Designer shows how to build an interactive emoji composer using HTML Canvas and Stimulus. Click face emojis, add accessories, drag them into position, and export the creation as an image, all in the browser with no external dependencies.
Check it out, Jessitron and I are podcasting again! You can catch the first episode, and find links to subscribe, on Graceful.Dev: “I’ve often wished I could fork myself…”
ruby-libgd: The Modern Ruby Image Library You've Been Sleeping On March 30, 2026 Reading time: 8 minutes Status: Benchmark-driven, production-ready Executive Summary After extensive benchmarking against RMagick, ChunkyPNG, and ruby-vips, ruby-libgd demonstrates overwhelming superiority in drawing operations (28x faster), pixel access (2.6x faster), sepia filtering (2.5x faster), and memory efficiency (3.7x less RAM). But speed … Continue reading ruby-libgd: The Modern Ruby Image Library You’ve Been Sleeping On
Another good week of closing parentheses. Merged the new Hanami Minitest. Added --test=minitest support to
hanami new. Merged undecorated exposures for views, along with some fixed tests to go along with it.Looped back to my earlier work on Hanami Action doing body parsing, and adjusted it to parse multipart bodies when there is no explicit format configured, which preserves the no-config support for multipart parsing we introduced in Hanami 2.3. This allowed me to remove the body parsing middleware from default Hanami apps. Begone, awkward solution! I also removed the deprecated action format config from the pre-2.3 era. Cleaning up!
The biggest parenthesis yet to close is the new…
English has plenty of irregular plurals. Criterion becomes criteria, not criterions. Rails handles many common ones already, but your domain might include words it doesn’t know about.
Instead of…
…accepting Rails’s best guess at a plural:
"criterion".pluralize #=> "criterions"
"matrix".pluralize #=> "matrices" # this one Rails knows!
Use…
…inflect.irregular to teach Rails the correct pair:
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.irregular "criterion", "criteria"
end
Now:
"criterion".pluralize #=> "criteria"
"criteria".singularize #=> "criterion"
Why?
Give irregular the singular and plural forms and Rails…
I noticed I kept switching between planning skills mid-session. One skill had the best forcing questions. Another had the best implementation structure. A third had the best review discipline. Also I think I have too many plugin collections and each seem to have a planning skill somehow.
So I analyzed 48+ planning skills across five repositories and combined the strongest elements into one flow. That is superplanning.
The problem with using multiple planning skills
When I started using Claude Code for serious product work, I had at least five planning-related skills available: ce:brainstorm for requirements, ce:plan-beta for implementation units, office-hours for pressure-testing ideas, pla…
Measuring Memory for Ruby Methods
When a process uses more memory than expected, you need to know which method is
responsible. ObjectSpace.memsize_of_all gives you a before/after delta.
The Pattern
require 'objspace'
GC.start
before = ObjectSpace.memsize_of_all
# ... run method here ...
after = ObjectSpace.memsize_of_all
puts "mem delta: #{((after - before) / 1024.0 / 1024.0).round(2)} MB"
GC.start forces a garbage collection cycle before measuring so prior
allocations don’t skew the result.
A Real Example
Two approaches to build a list of 50,000 user records. Save as measure_memory.rb:
require 'objspace'
# old approach - full AR objects with map
GC.start
before = ObjectSpace.memsize_of_all
scope = User.where.not(c…Over the past several months, there has been significant discussion, disagreement, and concern about RubyGems, Bundler, and Ruby Central’s role in stewarding RubyGems and supporting the Ruby ecosystem.
Because this matter has involved ongoing legal discussions, we have been limited in what we could say publicly. Our priority has been to resolve the situation responsibly and avoid escalating a conflict that affects the broader Ruby ecosystem.
With several new board members joining Ruby Central in recent months, it has also taken time to come up to speed on a complicated situation and begin charting a path forward.
Ruby Central’s actions during this period were taken in response to a breakdown…
Using Perfetto in ZJIT
Look! A trace of slow events in a benchmark! Hover over the image to see it get bigger.
img.hover-zoom:hover { transform: scale(2); transition: transform 0.1s ease-in; } img.hover-zoom:not(:hover) { transition: transform 0.1s ease-out; }
A sneak preview of what the trace looks like.
Now read on to see what the slow events are and how we got this pretty picture.
The rules
The first rule of just-in-time compilers is: you stay in JIT code. The second rule of JIT is: you STAY in JIT code!
When control leaves the compiled code to run in the interpreter—what the ZJIT team calls either a “side-exit” or a “deopt”, depending on who you talk to—things slow down. In a well-tuned…
For more than 8 years, we have been publishing detailed guides on how to upgrade Rails applications.
We have documented every minor version from Rails 2.3 through 8.1 in our Rails Upgrade Series and distilled our methodology into an ebook: The Complete Guide to Upgrade Rails

All of that knowledge comes from more than 60,000 developer-hours of hands-on upgrade work for companies of all sizes, from solo-founded SaaS products to huge Rails monoliths running at Fortune 500 public companies.
Today, we are making that methodology available to everyone as an open source Claude Code Skill: claude-code_rails-upgrade-skill.
Why a Claude Code Skill?
Claude Code is a powerful AI assistant for…
Conferences, AI Trends, and Sleepless Nights
Chris, Andrew, and David catch up on health, sleep deprivation, and the new Invincible season and Fallout. David shares some RubyConf CFP submissions news and this year’s broad conference themes. They discuss Andrew finishing difficult authentication work, touching on OAuth/SSO complexity and pricing, the idea of products built more for bots than humans, and where AI is proving useful, especially for debugging and research. The conversation eventually widens into a more skeptical look at the AI industry itself, touching on scraped code, deepfakes, surveillance, lobbying, and whether the promised productivity gains really match reality. Hit download now!
Links
Hi, it’s zzak. Let’s explore this week’s changes in the Rails codebase.
New Rails releases this week
Rails 7.2.3.1, 8.0.4.1, and 8.1.2.1 shipped as security releases, followed by 8.0.5 and 8.1.3 bugfix releases the next day.
Combine per-validator and top-level :if/:unless/:on in validates
validates now combines top-level and per-validator :if, :unless, and :on options instead of letting the inner options silently win.
validates :title, presence: { if: :local? }, if: :global?
# both conditions are now applied
Fix titleize to capitalize unicode lowercase letters
titleize now capitalizes Unicode lowercase letters as well as ASCII, so titleize("über ñoño") becomes Über Ñoño.
Late 2024 I published Rails Icons 1.0 (slighly off-topic, but I mentioned a modest few thousand downloads in that article; now it is close to 250k; I expect the same + a bit more for Perron). Today I like to re-introduce Rails Icons again to you: here is version 1.8.
(I did not expect SVG icons could be this exciting; and I have a few more ideas still! 🤯)
First I extracted the sync and SVG creation logic (the bit people have copy-pasted instead of using/contributing to the gem) into its own gem: Icons, I wrote about it here. The main goal was to make the “behind-the-scenes” architecture (syncing, normalizing icon names, etc.) available for others to build a similar gem for their framework…
Ruby 3.2.11 Released
Ruby 3.2.11 has been released. This release includes an update to the zlib gem addressing CVE-2026-27820.
Please see the GitHub releases for further details.
This is the final release of the Ruby 3.2 series. We will not provide any further updates, including security fixes, for the Ruby 3.2 series.
We recommend upgrading to Ruby 3.4 or 4.0.
Download
-
https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.11.tar.gz
SIZE: 19984344 SHA1: 9534a3aa08d2ccb4d3c50b1301b2da9a9b91c4ab SHA256: b3eeabd6636f334531db3ffdc3229eb05e524740e6c84fdc043720573cf2f8b2 SHA512:…
Worth the Squeeze
How Agentic Workflows Make Large-Scale Refactors Justifiable
Every mature codebase carries its history in the code. Patterns that were once best practice become deprecated. Constructs that were convenient when the project was small become performance bottlenecks at scale. As engineers, we see these opportunities for improvement all the time. We know exactly what should change. And yet, the question we keep coming back to is always the same: “Is it worth the squeeze?”
I’ve asked myself this question more times than I can count. The math rarely worked out. Hundreds of instances scattered across dozens of teams,…
CVE-2026-33658 (activestorage): Rails Active Storage has a possible DoS vulnerability in proxy mode via multi-range requests
#793 — March 26, 2026
Ruby Weekly
How to Install a Gem (It's Harder Than It Sounds) — As one of the people behind Bundler 1.0 and a former maintainer of RubyGems.org, and now working on gem.coop and rv, André knows a few things about how gems tick (big understatement). This post is full of ‘aha’ moments as he walks through installing a gem by hand, giving us an idea of what tools like gem and rv do for us.
André Arko
A Solo Founder Story: 'I Got Fed Up Chasing Contractors' — Tim tried hiring and outsourcing, but nothing fit. Then he found Bonsai. Now he gets reliable monthly Rails…
RubyMine 2026.1 is here! This release brings a range of improvements aimed at making Ruby and Rails development faster and more enjoyable.
You can get the new build from our website or via the free Toolbox App.
Let’s take a look at the highlights of this release.
AI
RubyMine continues to evolve as an open platform that lets you bring your preferred AI tools directly into your development workflow. With RubyMine 2026.1, working with multiple AI agents and integrating them into your IDE experience is now easier than ever.
Use more AI agents in RubyMine
In addition to Junie and Claude Agent, you can now choose more agents in the AI chat, including Codex. Additionally, C…
Ruby 3.3.11 Released
Ruby 3.3.11 has been released. This release includes an update to the zlib gem addressing CVE-2026-27820, along with some bug fixes.
Please see the GitHub releases for further details.
This is the last release of normal maintenance for the Ruby 3.3 series. After this release, Ruby 3.3 enters a security maintenance phase. During this phase, we will only backport security fixes and fixes for critical build issues, without any regular bug fixes.
The security maintenance phase is scheduled to last for one year, until the end of March 2027. At that point, official support for Ruby 3.3 will end. We recommend that you begin planning your migration to Ruby 3.4 or 4.0.
Download
March 25, 2026 Published on RubyStackNews Ruby is a high-level language. C is a low-level language. At some point, every serious Ruby application needs to cross that boundary. Maybe you need a cryptography library. Maybe a signal processing engine. Maybe a hardware interface. Maybe raw performance on a hot path. There are two ways to … Continue reading FFI: How Ruby Talks to C
Avo 4 Open Beta
CVE-2026-33635 (icalendar): iCalendar has ICS injection via unsanitized URI property values
Here are some additions I did for superpowers-ruby collection of plugins and skills. A fork from the well known superpowers plugin where I added some skills from compound-engineering-plugin which I think you should install it as it is.
The compound skill
I found that the compound skill from the folks at Every solves the problem of redisovering the same solution in various forms. The idea is simple: right after you and your agent fix something - while the context is still fresh - you capture what you actually did into a structured learning doc in docs/solutions/.
Next time you hit the same class of problem, the agent learns and uses it.
I think this is one of the most useful skills to add to…
How to Install a Gem
This post was originally given as a talk at SF Ruby Meetup. The slides are also available.
It’s more complicated than it sounds
Hello, and welcome to How To Install A Gem. My name is André Arko, and I go by @indirect on all the internet services. You might know me from being 1/3 of the team that shipped Bundler 1.0, or perhaps the 10+ years I spent trying to keep RubyGems.org up and running for everyone to use.
More recently, I’ve been working on new projects: rv, a CLI to install Ruby versions and gems at unprecedented speeds, and gem.coop, a community gem server designed from the ground up so Bundler and rv can install gems faster and more securely than ever before.
So, with that…
4.0.9 Released
RubyGems 4.0.9 includes enhancements, bug fixes and documentation and Bundler 4.0.9 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.9
RubyGems Release Notes
Enhancements:
- Fix: include owner role in
gem owner. Pull request #9403 by gjtorikian - Installs bundler 4.0.9 as a default gem.
Bug fixes:
- Fix: Ensure trailing slash is added to source URIs added via gem sources. Pull request #9055 by zirni
Documentation:
- [DOC] Fix link. Pull request #9409 by BurdetteLamar
Bundler Release Notes
Enhancements:
- Che…
I joined Jared again on the Dead Code Podcast to go a bit deeper on my post, The Death of a Software Craftsman. The outlook is kinda bleak, but plenty of digs at agile software practices :)
Hello again everyone! Long time no see 😆.
Rails Versions 8.0.5 and 8.1.3 have been released! These are regular bugfix releases.
These also include the changes from yesterday’s security releases, so if you haven’t upgraded yet you’ll get those fixes too.
The Rails 8.1 series will continue receiving bug fixes until October 2026. The 8.0 series will change to only receiving security updates in May next month, so this might be the last bug fix release in that series. See our Maintenance policy for more information.
CHANGES since 8.1.2
To see a summary of changes, please read the release on GitHub:
8.1.3 CHANGELOG To view the changes for each gem, please read the changelogs on GitHub:
GHSA-46fp-8f5p-pf2m (loofah): Improper detection of disallowed URIs by Loofah `allowed_uri?`

The final report for Ruby Association Grant on TutorialKit.rb—a toolkit for building interactive Ruby and Rails tutorials that run entirely in the browser using WebAssembly and WebContainers. Featuring a full-featured installer, agent-friendly development workflow, deployment pipelines, HTTP support, and real-world examples.
TutorialKit.rb, a toolkit for building interactive Ruby and Rails tutorials that run entirely in the browser, has reached the release candidate stage and is ready for general…

How do you measure product-market fit for a developer tool? A PMF scoring model from Evil Martians—a product development consultancy for developer tools startups—built on data from 37 devtools companies across AI, infrastructure, and cybersecurity. Five metrics, real benchmarks, and a dual score that tells you whether to invest in product or go-to-market.
Everyone talks about product-market fit. But what does it actually mean for a developer tools startup? "Are we close?" "Getting closer?" "What should we focus on to get closer?" At Evil Martians, we've spent nearly 20 years working with devtools companies—from…
CVE-2026-33306 (bcrypt): bcrypt-ruby has an Integer Overflow that Causes Zero Key-Strengthening Iterations at Cost=31 on JRuby
CVE-2026-33286 (graphiti): Graphiti Affected by Arbitrary Method Execution via Unvalidated Relationship Names
Supercharge Your Ruby on Rails Forms With Form Builders and Form Objects
Custom form helpers and builders can help reduce fragmentation if every developer in the team solves the same problem differently.

Have you come across instances where inside your Rails forms you need to fall back to plain input tags, like this form using a honeypot to prevent spam signups?
<%= form_with model: @signup do |f| %>
<%= f.email_field :email %>
<input type="hidden" name="utm_source" value="<%= params[:utm_source] %>">
<!-- Honeypot: should stay blank -->
<div class="hp" aria-hidden="true">
<label for="signup_company">Company</label>
<input type="text" id="signup_company" name="company" tabindex="-1" autocomplete="off">
</div>
<% end…Comb Shaped Slices
A friend who’s built and shut down companies in this space sat across from me at breakfast during a conference recently. He knows what I’m building: Chat with Work, an AI tool that lets you talk to your actual work data. He wanted to know what my plan was. I think he was a bit concerned.
“Add more integrations, finish the security assessment, market it well.” I said.
That didn’t help. “All those LLM providers are going to eat the whole market. They’ll ship every integration you can think of. If you want a slice of the pie, you need to pick a vertical and own it.”
I told him I was going to grab a T shaped slice of the pie instead.
He looked at me like I’d lost it.
Here’s the thing…
Although Devise is a fantastic authentication library, I’ve been reaching for Rails’s built in authentication generator since it was introduced in Rails 8. Almost all of my hobby apps are for a single user (me!) so I don’t really need all the features of devise.
Recently, I finally removed devise from an old project and replaced it with the generated authentication code. This turned out to be far easier than expected. Here are my notes:
Run the generator
The first thing to do is to run the generator:
rails generate authentication
This creates a bunch of files and overwrites some of our existing code, especially the User model. (Here’s an excellent walkthrough of the generated code.)
…
Hi friends!
Rails Versions 7.2.3.1, 8.0.4.1, and 8.1.2.1 have been released!
These are security patches addressing 10 security issues:
- An issue where in development mode, an exception could be printed without escaping. This could affect a developer running a server locally and clicking a malicious URL.
- Multiple potential XSS vulnerabilities in Action Pack, Action View, and Active Support
- Two potential DoS vulnerabilities in Active Storage related to range requests
- Two potential DoS vulnerabilities in Active Support related to number formatting
- A potential path traversal and glob injection vulnerability in Active Storage DiskService
- Insufficient filtering of metadata in…
We strongly recommend upgrading as soon as possible.
Older versions of Rails are unsupported, and users are recommended to upgrade to at least the 7.2 series. See our maintenance policy for details.
Here is a list of security issues that these releases address:
The Devtools PMF Compass

How do you measure product-market fit for a developer tool? A PMF scoring model from Evil Martians—a product development consultancy for developer tools startups—built on data from 37 devtools companies across AI, infrastructure, and cybersecurity. Five metrics, real benchmarks, and a dual score that tells you whether to invest in product or go-to-market.
Everyone talks about product-market fit. But what does it actually mean for a developer tools startup? "Are we close?" "Getting closer?" "What should we focus on to get closer?" At Evil Martians, we've spent nearly 20 years working with devtools companies—from…
Some English words don’t have a separate plural form. “Staff” is staff, “metadata” is metadata, “feedback” is feedback. Rails doesn’t always know this—it will happily generate a staffs table or a metadatas route if you let it.
Instead of…
…fighting Rails when it pluralises words that shouldn’t change:
"staff".pluralize #=> "staffs"
"metadata".pluralize #=> "metadatas"
"feedback".pluralize #=> "feedbacks"
Use…
…inflect.uncountable to tell Rails these words stay the same:
# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
inflect.uncountable %w[staff metadata feedback]
end
Now:
"staff".pluralize #=> "staff"
"metadata".pluralize #=>…Why?
…Can Ruby Read an X-Ray? Building a Medical Image Processor March 23, 2026 Published on RubyStackNews Nobody expects Ruby to process medical images. That is exactly why I tried it. This article is about building a medical image analysis prototype in pure Ruby using ruby-libgd as the rendering and pixel manipulation engine. No Python. No … Continue reading Can Ruby Read an X-Ray? Building a Medical Image Processor
Meet Duck Typer: your new duck typing friend
The Ruby language leans on duck typing rather than formal interfaces. “If it walks like a duck and quacks like a duck, it’s a duck.”
bodies = [poem, essay, case_study, user_manual].map(&:body)
These objects come from different classes but all respond to body,
so you can treat them uniformly. That’s informal polymorphism: no
type annotations, no ceremony.
Duck typing is great, but what I miss is enforcement. If one class implements a method and another forgets to, I want something to complain.
The interface is a living document
In Ruby, interfaces are implicit. They live in the public methods of your classes. Private methods are implementation details and not part of the…
My last weeks on logging represented the last of the major additions I wanted for our upcoming Hanami release. From here I need to start closing all my parentheses.
This week I started on the parenthetical that is Hanami Minitest. I now have that gem pretty much ready to go. Thanks to our community feedback, this now features a
test doblock-based DSL for declaring tests. I also settled on the naming, withHanami::Minitest::Test,Hanami::Minitest::RequestTestandHanami::Minitest::FeatureTestbeing the final names. This decision also gave me the chance to bring some of the basic setup code into the gem itself (such as setting up the Capybara basics) rather than having all of that be…
Direct link to podcast audio file
The promise of Breaking Change is that with every major version (this being the 60th episode of the program, but only the 53rd such release), I will break something. Well, I finally did it. I think I broke the show. Find out how by listening for yourself!
Want to be my friend? Drop me a line at justin@searls.co. Want to file a complaint with my supervisor? Forward your concerns to podcast@searls.co.
These links may rot, but alas—death comes for us all:
Spoken Latin
This post is an entry for the Spring 2026 Lobsters blog carnival, where participants are provoked to defend the superiority of our favorite language.¹
I accept the challenge, and I step forward to defend the honor of…
Latin.
Specifically, spoken Latin as a hobby language.
Why Latin?
tl;dr: because it has the unusual combination of being:
- no one’s native language, so everyone is a learner.
- a historical language, with texts ranging from two thousand years old to c…
Hi, it’s gregmolnar. Let’s explore this week’s changes in the Rails codebase.
Batch SQL statements when creating tables
This change batches the SQL statements during loading a database schema to improve the performance of the process.
Deprecate require_dependency
require_dependency is deprecated without replacement and will be removed in Rails 9.
Add MySQL lock option and extend algorithm to column Data Definition Language (DDL) operations
This pull request adds:
-
lock:option for MySQLadd_index,remove_index, and ALTER TABLE column operations (add_column,remove_column,change_column,rename_column) -
algorithm:option support extended to ALTER TABLE column operations on MySQL Com…
MySQL supports ALGORITHM = {DEFAULT|COPY|INPLACE|INSTANT} and LOCK = {DEFAULT|NONE|SHARED|EXCLUSIVE} to control how DDL…
Unraveling GitHub Actions & Modern Auth Challenges
On this episode, Andrew’s buried in messy authentication work spread across legacy code, Chris recounts a frustrating GitHub Actions debugging session, and David explains the mental drain of working across both Vue 2 and Vue 3 in the same application. They talk about using workflow run triggers, scheduled builds, and GitHub’s new Agentic Copilot workflows such as CI Doctor, Automatic Code Simplifier, and issue/PR management, while lamenting low-quality AI-generated PRs and paid AI code review tools. Andrew makes a special announcement about Blastoff Rails, they compare LazyVim, lazy.nvim, and Kickstart Neovim, we hear about Ruby 3.4.9 and its bug-fix release, and Marco Roth’s Herb…
Generated automatically by RubyEventsBot using ruby-libgd. Updated every 7 days. Updated by: https://github.com/koxya | Twitter: @koxya
IndieRails Podcast: The Conductor
I hopped on IndieRails with Jess and Jeremy (again). We covered a lot of ground in about 90 minutes. Quick business catch up and then dove into how AI has changed pretty much everything about how I work.
Some of the highlights:
Business Updates. Flipper Cloud almost doubled revenue last year, with most of the growth in the last few months. No AI headwinds on docs or conversion. Fireside is stabilizing — we flattened churn and had our first three month stretch of even or growing customers since taking it over. Momentum, the coworking space I invested in, is filling up and becoming a real community in South Bend.
Following the Inspiration. I'm a mood person. I follow the energy. Having multiple…
#792 — March 19, 2026
Ruby Weekly
Should RubyGems/Bundler Have a 'Cooldown' Feature? — RubyGems’ maintainer reflects on the idea, quickly gathering steam with other package managers (e.g.), of having a waiting period before newly released packages are installed. Hiroshi says yes, but as an opt-in feature, as it's no silver bullet.
Hiroshi Shibata
No AI Code in Production Directive — Have you heard Amazon now requires senior engineer approval for all AI-generated code after several severity-0 incidents? Should you ban it, too? We say: there's no such thing as AI code. There's just code.
…Managing bulk file transfer to Amazon Simple Storage Service (Amazon S3) can be complex when transferring directories containing multiple files and subdirectories. AWS SDK for Ruby Transfer Manager (aws-sdk-s3 version 1.215) now supports directory upload and download. This feature can help streamline bulk transfers by providing multipart handling and parallelism options.
Previously, uploading directories to Amazon S3 required manual iteration and handling. You also had to manage multipart uploads for large files and implement parallelism for performance. With directory support in Transfer Manager, you can handle this with a single method call that automates the process. In this post, we…
Recently I had to build something using the canvas element. Today I’ll show you how to build an interactive emoji composer using HTML Canvas and Stimulus. Click emojis to add them to a canvas, drag them around and export your creation as an image. It is quite fun (coming from an emoji connoisseur)! 😎👍

Click a face emoji, add some accessories, position everything just right and download your custom creation. All running in the browser with no external dependencies.
The HTML
Start with a simple layout that divides the screen into a canvas area and emoji picker:
<div data-controller="canvas-composer image-exporter">
<div class="grid…Have you ever looked at a VitePress documentation site and felt a little jealous?
The sidebar navigation. The “On this page” outline on the right. The search that pops up with /. The homepage that actually looks like a product page, not a README with a nav bar. Dark mode that just works. Code blocks with copy buttons and language labels. It all looks like someone sat down and designed the whole experience.
Because someone did. VitePress is genuinely great. And Ruby developers know it, because some of the most visible projects in our community are shipping their docs on VitePress. Not on a Jekyll theme, not on a Ruby tool. On a JavaScript static site generator built for Vue.
I don’t blame…
While upgrading RuboCop in one project, I noticed three new style cops in v1.85.0. I took a close look at them and my recommendation is to enable them all.
Let's start.
The 3 Cops
The cops are:
-
Style/SelectByKind(PR #14808) -
Style/SelectByRange(PR #14810) -
Style/PartitionInsteadOfDoubleSelect(PR #14923)
Each is marked as correctable so if you run this you can automatically apply the changes.
1) Style/SelectByKind
This one rewrites class/module filtering from select/reject to grep/grep_v.
# before
array.select { |x| x.is_a?(Foo) }
array.reject { |x| x.is_a?(Foo) }
# after
array.grep(Foo)
array.grep_v(Foo)
From the PR discussion, two details mattered to me:
The name changed from
Sele…
I had a simple index.html page, a marketing site for a client in Spanish.
They asked an English version too, so I opened the chat to Claude’s Opus 4.5 model and asked it to create a near-identical en/index.html with content translated.
Easy peasy.
I opened both files side by side and skimmed, they looked the same with lines in different languages. But I’m used to testing changes, and agents find things to fix before I start more careful checking. While I had this thought, the client recalled they’d need a version in Portuguese as well. “Sure”.
Now, would they synchronize updates in Spanish to the other two languages? Content and design will surely drift.
The solution
I used Claude’s /…
2D Histograms in Pure Ruby March 18, 2026 Published on RubyStackNews One of the most useful tools in exploratory data analysis is the 2D histogram. Not the bar chart kind — the density map kind. Given a cloud of points, it answers a simple question: where do most of them live? This article shows how … Continue reading 2D Histograms in Pure Ruby
Intro
Since the post at the end of last year, ZJIT has grown and changed in some exciting ways. This is the story of how a new, self-contained optimization pass causes ZJIT performance to surpass YJIT on an interesting microbenchmark. It has been 10 months since ZJIT was merged into Ruby, and we’re now beginning to see the design differences between YJIT and ZJIT manifest themselves in performance divergences. In this post, we will explore the details of one new optimization in ZJIT called load-store optimization. This implementation is part of ZJIT’s optimizer in HIR. Recall that the structure of ZJIT looks roughly like the following.
flowchart LR
A(["Ruby"])
A -->…The Rails Infrastructure team has been working on making Bundler faster and our work has paid off. A cold bundle install is 3x faster on a Gemfile with 452 gems compared to Bundler 2.7. But “faster” only means something if everyone agrees on what’s being measured. If two people are running benchmarks with different definitions of “cold install” or different cache states, the results aren’t comparable. We needed a shared tool that would give us confidence, both internally and externally, that we’re tackling the right problems and actually making Bundler faster. And along the way we learned when Claude can be helpful and when to not outsource our own expertise and thinking.
What affects…
RubyLLM 1.14 ships a full chat UI generator. Two commands and you have a working AI chat app with Turbo streaming, model selection, and tool call display, in under two minutes. The demo above shows the whole thing: new Rails app to working chat in 1:46, including trying it out.
Why This Matters
RubyLLM turned one last week. 1.0 shipped on March 11, 2025 with Rails integration from day one: ActiveRecord models, acts_as_chat, Turbo streaming, persistence out of the box. 1.4 added the install generator. 1.7 brought the first scaffold chat UI with Turbo Streams. 1.12 introduced agents with prompt conventions. Each release got closer to the same thing: AI that works the way Rails works.
1.14…
GHSA-qmpg-8xg6-ph5q (action_text-trix): Trix has a Stored XSS vulnerability through serialized attributes
GHSA-57hq-95w6-v4fc (devise): Confirmable "change email" race condition permits user to confirm email they have no access to
Ruby on Rails — Complete Reference of Methods, Classes & Features Not in Ruby March 17, 2026 Rails is much more than a framework on top of Ruby — it adds hundreds of methods, classes, and abstractions that plain Ruby simply doesn't have. This is a complete reference of everything Rails brings to the table, … Continue reading Ruby on Rails — Complete Reference of Methods, Classes & Features Not in Ruby
Not the usual content on this blog, bnut this is an interesting story to tell I believe. I own a 2015 Chrysler Town and Country minivan. It is a really good car and filled with electric components. The side doors, the booth, there are 2 screens a DVD player and a bunch of other stuff. Awesome when all is good, not so much when something breaks.
NO AI CODE IN PRODUCTION DIRECTIVE
At SINAPTIA, we started enforcing a no “AI code in production” directive.
LOL, no. We are not the next tier of Luddites! We started using AI-assisted code generation a little over a year ago, and from the looks of it, we are going to use it even more in the near future. AI is here to stay, and programming will never be the same, what a time to be alive and so on, and so on…
But also, in a couple of years, we’ll all lose our jobs. What a time to be alive, indeed.
We continually ask ourselves: what’s the AI capable of? Can it really replace us? Can it change the way we work? Will it make our problems simpler? Or there will be another kind of problems, more problems? Are we attending the…
🎙️ Merge Commits podcast - freeCodeCamp: Which Devs Are Screwed?
Direct link to podcast audio file
Quincy Larson over at freeCodeCamp had me on their podcast to discuss how the rapidly changing software industry is impacting junior developers and what they can do about it. I don't normally spend time talking about this stuff, because I started programming in the 90s and can't claim to know anything about what it's like to just be starting now. I've also always discouraged people from getting into software development unless they're super passionate about it, which has been out of step with the "learn to code" hype train that gathered steam over the last fifteen years only to run into a brick wall recently.
His audience is way larger and composed…



