Development teams in the cruise line industry face a unique set of constraints. Their software must handle complex booking logic, real-time inventory across multiple ships, and passenger data that spans dozens of nationalities. At the same time, the pressure to reduce operational waste—whether that's server energy, developer hours, or code that gets rewritten every two years—has never been higher. Choosing a Ruby web framework is more than a technical preference; it's an ethical decision about how we spend our time and computing resources.
This guide compares Ruby on Rails and Hanami through a zero-waste development lens. We'll look at where each framework excels, where it falls short, and how to decide which one aligns with a long-term, sustainable engineering practice. The cruise line context isn't just window dressing—it shapes the kind of trade-offs that matter, from database migrations to background job reliability.
Who Must Choose and Why the Timeline Matters
The decision between Rails and Hanami typically arises at one of three moments: when a startup cruise tech company is building its first product, when an established line is modernizing a legacy system, or when a team is spinning up a new microservice for a specific feature like onboard dining reservations. Each scenario has a different tolerance for risk and a different timeline.
For a greenfield project with a tight launch date, the pressure to ship quickly often favors Rails. Its vast ecosystem of gems, mature documentation, and large community mean that most problems have already been solved. A team of three developers can scaffold a booking API in a week. But that speed comes at a cost: Rails' monolithic structure can lead to tangled dependencies if not disciplined. Over time, the codebase accumulates what some call 'convention debt'—the friction of working around assumptions that don't fit your domain.
Hanami, on the other hand, appeals to teams that have the luxury of a longer runway. Its modular architecture encourages separating concerns from the start, which can reduce waste during maintenance. However, the smaller community means fewer pre-built solutions. A team might need to write custom middleware for something as common as OAuth integration. The timeline for a Hanami project is often 20-30% longer initially, but proponents argue that the savings appear in the second and third years of the project.
For cruise line systems, where seasonal peaks (summer, holidays) demand stability, the choice also affects how quickly you can respond to production incidents. Rails' familiarity means more developers can jump in to fix a bug at 2 AM. Hanami's clarity of structure means that when a bug is found, it's easier to isolate and fix without side effects. The right answer depends on your team's composition and the expected lifespan of the software.
When Zero Waste Means Choosing Speed
If your primary waste concern is developer time—because every hour spent on boilerplate is an hour not spent on passenger experience—then Rails' generators and conventions are hard to beat. The framework's 'convention over configuration' philosophy reduces decision fatigue. New hires can be productive on day two. For a cruise line that needs to iterate on a booking flow rapidly, that's a direct reduction in waste.
When Zero Waste Means Choosing Longevity
If your waste concern is technical debt—code that becomes unmaintainable and must be rewritten—then Hanami's emphasis on clean boundaries pays off. Each component is a gem that can be tested and replaced independently. A poorly performing payment module can be swapped without touching the rest of the app. In a cruise line context, where the booking system might be expected to last a decade, that modularity prevents the kind of rot that leads to full rewrites.
The Option Landscape: Three Approaches to Ruby Web Development
While the headline comparison is Rails vs. Hanami, the real landscape includes a spectrum of approaches. Teams aren't limited to a binary choice; they can blend patterns or adopt a third path.
Approach 1: Full Rails Monolith. This is the default for most Ruby shops. You get ActiveRecord, Action Cable for real-time features (like live cabin availability updates), and a rich testing ecosystem. The risk is that as the app grows, the monolith becomes a 'big ball of mud.' Cruise line apps that start as a single Rails app often end up with a separate admin panel, a public API, and a worker process for background jobs—all within the same codebase, leading to accidental coupling.
Approach 2: Modular Rails with Engines. Rails supports engines (mini-applications) that can be mounted inside a host app. Some teams use this to simulate Hanami's modularity while staying in the Rails ecosystem. For example, a cruise line could have an engine for bookings, one for crew management, and one for onboard activities. This approach reduces waste by reusing Rails' tooling while enforcing boundaries. The downside: engines add complexity to the load path and can be tricky to test in isolation.
Approach 3: Hanami with a Service Layer. Hanami's architecture naturally separates entities, repositories, and actions. A team can build a Hanami app that treats each bounded context as a separate Hanami application, communicating via HTTP or message queues. This is the most modular option, and it aligns well with a zero-waste ethic because it prevents cross-context pollution. However, it requires disciplined team conventions to avoid creating a distributed monolith where services are tightly coupled by shared databases or synchronous calls.
For cruise line teams, the choice often comes down to how much of the system is expected to change over time. If the booking logic is stable but the payment gateway changes every few years, Hanami's separation makes those swaps painless. If the entire product is still being discovered, Rails' speed allows for cheaper experimentation.
Why Not Sinatra or Roda?
Some readers might wonder why we're not considering lighter frameworks like Sinatra or Roda. Those are excellent for small services, but for a typical cruise line application with a dozen models, background jobs, and a web frontend, they require too much manual assembly. The waste of reinventing authentication, session management, and database migrations outweighs the simplicity gain. Rails and Hanami both provide these essentials out of the box.
Comparison Criteria: What Matters for a Zero-Waste Ethic
To evaluate frameworks through a sustainability lens, we need criteria beyond feature lists. Here are the dimensions that matter when your goal is to minimize waste—of time, energy, and code.
1. Onboarding Efficiency. How quickly can a new developer become productive? Rails wins here because of its ubiquity. Hanami's learning curve is steeper, but the payoff is that developers understand the full stack rather than relying on magic.
2. Code Redundancy. Does the framework encourage DRY (Don't Repeat Yourself) or does it lead to copy-paste patterns? Rails' generators can create repetitive code if not used carefully. Hanami's structure naturally leads to more explicit code, which can be more verbose but less redundant.
3. Testability. A zero-waste ethic values code that is easy to test, because bugs caught late are expensive. Hanami's dependency injection and clear boundaries make unit testing straightforward. Rails' tight coupling to ActiveRecord can make tests slower and more brittle, though tools like RSpec and FactoryBot mitigate this.
4. Deployment Footprint. How much server memory does a typical app consume? Rails apps are known for being memory-heavy, especially with many gems. Hanami apps are leaner because they load only the components needed. For a cruise line running dozens of microservices, the cumulative memory savings can reduce cloud costs and energy consumption.
5. Ecosystem Maturity. A mature ecosystem reduces waste by providing battle-tested solutions. Rails' gem ecosystem is vast, but it also includes many abandoned or poorly maintained gems. Hanami's smaller ecosystem means fewer choices, but each gem is more likely to be maintained by the core team or a dedicated community.
6. Long-Term Maintainability. How does the codebase age? Rails apps often require periodic upgrades to keep up with framework changes, which can be disruptive. Hanami's versioning is more conservative, and its modular nature means you can upgrade components independently. For a system expected to last 5-10 years, this is a significant waste-reduction factor.
Weighting the Criteria for Your Context
Not all criteria are equal for every team. A startup building a minimum viable product might prioritize onboarding efficiency and ecosystem maturity. A mature cruise line with a stable product might prioritize testability and long-term maintainability. The key is to be explicit about your weights before making a choice.
Trade-Offs Table: Rails vs. Hanami at a Glance
| Dimension | Ruby on Rails | Hanami |
|---|---|---|
| Onboarding speed | Fast (large community, many tutorials) | Moderate (smaller community, fewer guides) |
| Code organization | Convention-based, can become tangled | Modular, explicit boundaries |
| Memory footprint | Higher (full stack loaded) | Lower (lazy loading of components) |
| Testing culture | Strong ecosystem (RSpec, Capybara) | Built-in dependency injection, easier unit tests |
| Gem quality | Many options, some abandoned | Fewer but curated |
| Upgrade effort | Major versions require significant changes | Minor breaking changes, easier incremental upgrades |
| Best for | Rapid prototyping, small teams, short-lived projects | Long-lived systems, large teams, high modularity needs |
The table above summarizes the key trade-offs. Notice that neither framework is universally superior; the right choice depends on your project's expected lifespan and team dynamics. For a cruise line, a booking engine that will be maintained for a decade might lean toward Hanami, while a promotional microsite for a new ship might be better built with Rails.
When the Table Doesn't Tell the Whole Story
The table simplifies real-world complexity. For instance, a Rails app can be made more modular using engines or service objects, but that requires discipline. A Hanami app can be made faster to prototype by using scaffolding generators, but those are less mature than Rails'. The table is a starting point, not a verdict.
Implementation Path After the Choice
Once you've chosen a framework, the next step is to plan the implementation to minimize waste. This section outlines a path for both Rails and Hanami, focusing on practices that align with a zero-waste ethic.
If you chose Rails: Start with a minimal set of gems. Resist the temptation to add every popular gem at the beginning. Use Rails' built-in features first—Active Job for background tasks, Action Mailbox for email processing—and only add a gem when you have a concrete need. Structure your app using service objects for business logic and keep controllers thin. Consider using the 'rails app:update' task to stay current with minor versions, but delay major version upgrades until you have a clear migration plan. For database migrations, use reversible migrations and test them in a staging environment that mirrors production data volume.
If you chose Hanami: Start by defining your bounded contexts. Each context should be a separate Hanami application within the same project. Use Hanami's repositories to encapsulate database queries, and use entities for domain logic. For inter-context communication, prefer asynchronous messaging (e.g., using RabbitMQ or Redis queues) over direct HTTP calls to avoid coupling. Write integration tests that verify the boundaries between contexts. Since Hanami's community is smaller, invest time in writing internal documentation for patterns that your team adopts.
Common to both: Implement a robust monitoring and logging strategy from day one. Use structured logging (JSON format) so that logs can be ingested by tools like Elasticsearch or Loki. Set up performance monitoring to catch memory leaks early. For cruise line applications, which often have seasonal traffic, use auto-scaling groups and load testing to ensure the system handles peak loads without wastefully over-provisioning resources.
Database Schema Design
Both frameworks benefit from careful schema design. Avoid polymorphic associations where possible—they are a common source of confusion and performance issues. Use indexes wisely, and consider partitioning large tables (e.g., booking history) by date. For Rails, use ActiveRecord's 'strict_loading' to prevent N+1 queries. For Hanami, use repositories to enforce consistent query patterns.
Background Job Strategy
Background jobs are essential for cruise line systems: sending confirmation emails, syncing inventory between ships, processing payments. In Rails, Sidekiq is the de facto standard. In Hanami, you can use Sidekiq as well, but you'll need to configure it manually. Consider using a job queue that supports retries and dead letter queues. For both, monitor job queues and set up alerts for failed jobs to prevent silent data loss.
Risks If You Choose Wrong or Skip Steps
Choosing a framework that doesn't fit your context can lead to significant waste. Here are the most common risks and how to mitigate them.
Risk 1: Over-engineering with Hanami. A small team building a simple CRUD app may spend too much time on modularity that they don't need. The result: slower time to market and a codebase that is more complex than necessary. Mitigation: Start with a single Hanami app and only split into multiple apps when you feel pain from coupling. Use Hanami's built-in slice feature (a lighter form of modularity) before going full multi-app.
Risk 2: Under-engineering with Rails. A large team building a complex system may create a monolithic Rails app that becomes unmaintainable. The result: frequent regressions, long build times, and high cognitive load. Mitigation: Use Rails engines to separate concerns from the start. Enforce coding standards with RuboCop and use tools like Brakeman for security analysis. Invest in a comprehensive test suite that runs in parallel.
Risk 3: Skipping the upgrade path. Whether you choose Rails or Hanami, deferring framework upgrades leads to technical debt. Security patches for older versions stop being released, and upgrading becomes a painful, high-risk project. Mitigation: Schedule regular upgrade sprints (e.g., every six months). Use a dependency management tool like Dependabot to stay aware of updates. For Rails, follow the official upgrade guides. For Hanami, check the changelog and release notes.
Risk 4: Ignoring the human factor. A framework that your team dislikes will lead to low morale and high turnover. If your team is experienced in Rails, forcing Hanami may backfire. Mitigation: Involve the team in the decision. Run a small pilot project in the chosen framework before committing to a full-scale build. Gather feedback on developer experience and adjust accordingly.
What Happens If You Don't Plan for Growth
A common mistake is to assume that the initial choice will scale without changes. In reality, every system evolves. A Rails app that starts as a monolith may need to be broken into services later. A Hanami app that starts with too many boundaries may need to be consolidated. The key is to design for change: use well-defined interfaces, avoid shared databases between services, and document architectural decisions. This reduces the waste of rewriting large portions of the codebase.
Mini-FAQ: Common Questions About Rails vs. Hanami for Cruise Line Systems
Q: Can I use Rails and Hanami together in the same project?
A: Yes, but it's rarely advisable. You could run a Rails app for the public-facing website and a Hanami app for internal APIs, but maintaining two frameworks adds overhead. A better approach is to choose one and use its modularity features to achieve separation.
Q: Which framework is better for real-time features like cabin availability updates?
A: Rails has Action Cable built-in, which makes WebSockets easy to implement. Hanami doesn't have a native solution, but you can integrate with libraries like Faye or use a separate service for real-time updates. For most cruise line applications, Rails is simpler for real-time.
Q: How do the frameworks handle API versioning?
A: Rails commonly uses URL-based versioning (e.g., /api/v1/bookings) with namespaced controllers. Hanami's modular structure makes it natural to create separate applications for each API version, which can be deployed independently. Hanami's approach is cleaner for long-lived APIs.
Q: What about testing? Is one framework easier to test?
A: Hanami's dependency injection makes unit testing easier because you can mock dependencies without monkey-patching. Rails' integration tests are well-supported, but unit tests often require workarounds. For a large codebase, Hanami's testability can reduce waste from flaky tests.
Q: Which framework is more energy-efficient?
A: Hanami apps typically use less memory, which translates to lower energy consumption per request. However, the difference is marginal for small apps. For large systems with many instances, the cumulative savings can be significant. If your cruise line runs dozens of microservices, Hanami's lower footprint is a sustainability win.
Q: Should I migrate an existing Rails app to Hanami?
A: Only if the maintenance pain exceeds the migration cost. Migrating a mature Rails app to Hanami is a major undertaking. A better strategy is to extract new features as Hanami services while leaving the existing Rails app intact. This incremental approach reduces risk and allows you to evaluate Hanami without a full rewrite.
Common Misconception: Hanami Is Just 'Rails but Better'
Some developers view Hanami as a 'better Rails' because it avoids some of Rails' design flaws. In reality, Hanami is a different paradigm. It's not a drop-in replacement; it requires a different mindset. Teams that approach Hanami with Rails expectations often struggle. It's better to think of Hanami as a tool for a specific set of problems—those where long-term maintainability and modularity are paramount—rather than as a universal upgrade.
Recommendation Recap Without Hype
After weighing the criteria, trade-offs, and risks, we recommend the following decision framework for cruise line development teams:
Choose Rails if: your team is small (fewer than 5 developers), you need to ship a minimum viable product in under three months, or you are building a short-lived application (expected lifespan under 3 years). Rails' speed and ecosystem will minimize waste in the short term.
Choose Hanami if: your team is experienced in Ruby (not necessarily Hanami), you are building a system that will be maintained for 5+ years, or you have multiple teams working on different bounded contexts. Hanami's modularity will prevent the accumulation of technical debt that leads to rewrites.
Consider a hybrid approach if: you have a legacy Rails app that is stable but need to add new features. Build new services in Hanami and connect them via APIs or message queues. This allows you to gain experience with Hanami without a risky migration.
Ultimately, the zero-waste ethic is not about picking the 'perfect' framework. It's about making a conscious choice based on your specific constraints and then committing to practices that minimize waste over the life of the project. Both Rails and Hanami are capable tools; the waste comes from using the wrong one for your context or from neglecting maintenance. Choose deliberately, build cleanly, and revisit your decision as your project evolves.
For teams that want to dig deeper, we recommend reading the official documentation for both frameworks, studying open-source projects built with each, and running a small proof-of-concept before committing. The time invested in research is never wasted—it's the most efficient way to avoid a costly mistake.
Comments (0)
Please sign in to post a comment.
Don't have an account? Create one
No comments yet. Be the first to comment!