Skip to content
Frameworks Article

Hanami 3.0 and the Case for Modular Ruby

The newly released web framework offers a strict, zero-allocation-focused alternative to the monolithic conventions of Rails.

Emeka Okafor
Emeka Okafor
Security Editor · Jul 1, 2026 · 5 min read
Hanami 3.0 and the Case for Modular Ruby

For nearly two decades, writing web applications in Ruby has meant accepting a single, monolithic paradigm. Rails won the framework wars by offering a massive, shared global namespace, heavy reliance on Active Support, and magical autoloading. But as codebases scale, that magic often curdles into tight coupling and unpredictable side effects.

Hanami has long pitched an alternative: a framework built on explicit dependency injection, strict architectural boundaries, and container-based design. With the release of Hanami 3.0, this alternative moves from an intriguing architectural exercise to a highly optimized, production-ready framework. By introducing first-class mailers, built-in internationalization, and dramatic performance improvements, Hanami 3.0 presents a compelling case for developers looking to escape the global state of traditional Ruby applications.

The Architecture of Slices and Containers

At the core of Hanami is the concept of "slices" (isolated, self-contained modules that partition an application's domain). Unlike Rails engines, which often bleed into one another through shared global namespaces, Hanami slices enforce strict boundaries.

In Hanami 3.0, this modularity is reinforced. For example, the newly integrated internationalization (i18n) engine does not simply inject a global translation helper. Instead, it instantiates a self-contained translation backend inside the application container and each individual slice. Translations live in config/i18n/ within their respective slices, preventing the giant, unmaintainable translation files that plague large Rails apps.

Dependency injection is handled via the Deps mixin, which connects components registered in the application container. This approach eliminates the need for global class references, making components highly testable and decoupled.

The Performance Equation: Zero-Allocation Focus

The headline metric for Hanami 3.0 is a 3x throughput increase over HTTP and a massive reduction in memory allocations. But the engineering behind this is what matters.

Historically, dependency injection frameworks in dynamic languages have suffered from initialization overhead. If every web request triggers the resolution and instantiation of a complex graph of objects, performance tanks. Hanami 3.0 solves this by memoizing container components by default. Components are resolved exactly once and then reused across requests.

The impact of this shift, combined with configuration snapshotting in Hanami::Action and Hanami::View, is stark:

xychart-beta
title "Object Allocations: Hanami 2.3 vs 3.0"
x-axis ["Action (2.3)", "Action (3.0)", "Render (2.3)", "Render (3.0)"]
y-axis "Allocations" 0 --> 110
bar [88, 17, 100, 42]

By snapshotting configuration up front instead of recomputing it per request, a minimal action drops from 88 allocations to just 17. Views no longer decorate exposures by default, cutting minimal render allocations from 100 to 42. For an action resolving a graph of nine components, this translates to 14x fewer allocations and a drop in p99 tail latency from 89ms to 4ms. The garbage collector simply has less work to do.

Developer Angle: Adoption, Trade-offs, and Migration

To adopt Hanami 3.0, you need Ruby 3.3 or newer. Booting a new project is straightforward, and the framework now officially supports Minitest alongside its traditional RSpec default:

$ hanami new my_app --test=minitest

The new Mailer integration is a prime example of Hanami's dependency injection model. Mailers are now first-class objects that can be injected anywhere via the Deps mixin:

module Bookshelf
  module Mailers
    class Welcome < Bookshelf::Mailer
      from "welcome@bookshelf.test"
      to { |user:| user.email }
      subject { |user:| "Welcome to Bookshelf, #{user.name}!" }
      expose :user
    end
  end
end

You can deliver it by calling .deliver on the injected dependency. SMTP delivery works out of the box, and in-memory delivery is used during testing to allow easy inspection of sent emails.

However, migrating an existing Hanami 2.x application to 3.0 will require some refactoring. The team has retired hanami-validations, opting instead to have Hanami::Action check dry-validation contracts directly. The core controller gem has also been renamed from hanami-controller to hanami-action.

Furthermore, views now default to undecorated exposures. If your existing application relies on automatic decoration of view variables, you will need to adjust your rendering logic.

Early testers have also noted minor papercuts. For instance, the new SQL logging syntax highlighting (driven by the rouge gem) defaults to the dark gruvbox theme. If you run a light terminal theme, you will need to set the HANAMI_SQL_THEME environment variable to something like github or pastie to keep your logs readable. There are also reports of encoding issues with file uploads under certain Rack configurations that developers upgrading from 2.x should watch out for.

The Verdict

Hanami 3.0 is a mature, highly performant alternative to the monolithic conventions of Rails. It is not a drop-in replacement, nor does it try to be. The learning curve is steeper, and you must think explicitly about dependency injection and architectural boundaries. But for teams building long-lived, complex applications where low latency and clean separation of concerns are paramount, Hanami 3.0 is a compelling choice.

Sources & further reading

  1. Hanami 3.0: In Full Bloom — hanakai.org
  2. Hanami 3.0: In full bloom - Announcements - Ruby Users Forum — rubyforum.org
  3. Hanamiyama in Full Bloom - Fukushima Travel — fukushima.travel
  4. Help us test the Hanami 3.0 release candidate - announcements - Hanakai — discourse.hanakai.org
Emeka Okafor
Written by
Emeka Okafor · Security Editor

Emeka has spent over a decade tracking threat actors, vulnerability disclosures, and the evolving landscape of application security, bringing a sharp continent-spanning perspective to his reporting. He's known for translating dense CVE advisories into clear, actionable context that developers and security teams alike actually read.

Discussion 0

Join the discussion

Sign in or create an account to comment and vote.

No comments yet

Be the first to weigh in.

Related Reading