56 comments

[ 4.0 ms ] story [ 94.7 ms ] thread
Down in the article:

> Well, the primary answer is that Hanami isn’t trying to unseat Rails.

Exactly. Clickbaity titles are still necessary in 2018 apparently.

I've worked with one of Hanami's maintainers for a while, working on a Rails app. I have been following the project for a while, it's definitely not a Rails killer. I'm not sure why these conversations are always brought up. But hey, at least the "Elixir/Phoenix will kill Rails" discussions have stopped for a few months.

> at least the "Elixir/Phoenix will kill Rails" discussions have stopped for a few months.

At least until the next Phoenix version is released :-)

I've been doing Rails development for ~10 years and maybe it's just a sign that I'm getting older, but for me the biggest problem isn't Rails, it's Ruby.

In the past year or so I've done a lot of more modern JS development (with Babel and Flow) and toyed around with Elixir and ReasonML. Ruby hasn't seen much change in the past couple of years (granted it's much more mature than Elixir/Reason) and while it was a boon to developer productivity and happiness compared to the languages of the time, I think we've probably found a better balance in type systems these days than Ruby and the like did at the time.

Maybe it's just legacy codebases, but manually reasoning about types is huge time sink and are one of our leading causes of production errors. Explicit typing also informs better design (I've seen many a Ruby method have return type of `String | Array | nil`). Unit tests help, but why outsource that to tests and guard statements (where you have to check every type) when a computer can do that for you?

You may enjoy using Contracts and the Dry-rb suite. It makes ruby behave in a more functional way without sacrificing the extreme flexibility that is inherit in the language.

There was a good blog post about this from Thomas Reynolds the developer of Middleman a little while ago[0]

[0] https://awardwinningfjords.com/2015/03/03/my-weird-ruby.html

Nope, sorry but just nope. I use dry-validations and it’s fine for what it is, but unless this stuff is at the language level it’s just a hack and janky to use, which sacrifices one of ruby’s main attractions - language aesthetics.

I agree with parent, ruby is a pain to work in, especially if you’ve drunk the FP koolaid. I’m back doing rails again after a while doing react front end stuff and a bunch of own time elixir. Ruby needs to allow more functional programming imo.

Careful, the dry-rb people are very sensitive. I posted a similar "nope" comment on r/Ruby a few years ago and now I have massively negative karma on that sub.
Sure, it's definitely a hack on top of the language, but sometimes you don't have the option to rewrite and those tools can make your code more functional without having to switch stacks. It's not perfect, it's just a bit better than the alternative in many cases.
In my personal experience, Dry-rb is the "bargaining" stage of grief over the current state of Ruby and Rails. When you finally reach "acceptance," you move on to another stack entirely.
Exceptions are also problematic in Ruby. It quickly becomes impossible to look at any method and answer the question "what exceptions can this raise?"

Ruby has rich exception handling mechanisms, but everyone just uses "rescue" without any arguments (or worse, "rescue Exception") because of the elusiveness of the answers to that question.

Most of these problems arise from bad engineering cultures though, not the language itself.
Yes, you can absolutely make Exceptions a first-class domain concept, I've been doing this in a worker instrumentation that I've been doing. I have a custom error class that inherits from StandardError, and the exception handling code handles these custom errors differently than other errors.

This way knowledge can be slowly wrapped around the failure modes as they get seen.

Discipline can only get you so far. If you call a method coming from a third-party gem, you will still have no idea what exceptions could be raised by it no matter how well you've handled exceptions sourced from your own code.
That's true, but it's also possible to prevent these problems within a language, as Java does: https://docs.oracle.com/javase/tutorial/essential/exceptions...

(Not trying to start Java v Ruby here, just looking at how exceptions work)

It definitely is, but what happens when you'd like to use the other behavior? There's definitely certain occasions in which you want to use the not-best way to do thing. Leaving the choice to the programmer rather than removing the feature from the language is the way to go imo.
(comment deleted)
> I've been doing Rails development for ~10 years...

I'm a long time Rails dev as well. IMHO the main problem with the Ruby ecosystem is that the libraries haven't moved on into the current day and age. I find myself building more and more projects in something like Java or Python because those ecosystems have the firepower of the ML, AI, data processing libraries. And while I'd still say Rails is the best for building pure web and rest API stuff, Java and Python have gained a lot of ground and when all your real app power is in Python or Java a lot of times its not worth wrapping your core apps in another runtime just to provide a rest interface.

Any other rails / ruby devs experiencing this?

(comment deleted)
I hesitate to even say that I'm a Rails guy anymore because I've modified it for my own purposes so heavily that it's fundamentally a different thing[0] but I'm also a data scientist and when I need data science I just use python. It's so much easier to just have python / cython / numba and Rails share databases and just communicate through that when needed. For the stuff that can't communicate through the DB I can either fork off traffic to python in nginx or communicate through something that unix provides (pipes, ports, files, 0mq, whatever).

Ruby / Rails is so much more productive for me. No other language nails so many features as well as Ruby. Blocks are great, the meta-programming is natural and easy to debug, c-extensions are easy, and I generally like the balance it strikes with types. Couple quibbles here and there, to be sure, but usually the DB acts as my type enforcer and the high degree of test coverage covers the rest. Plus whenever I think something is risky I just throw in an explicit type coercion or exception, but it is rare.

I find people generally fall into one of three categories: Documentation enthusiasts, type enthusiasts, or test enthusiasts. Because I prefer human readable code I prefer meta-programming and because I prefer meta-programming I prefer tests over types or documentation. Though I don't pretend it's drawback-free, it is the environment that makes me happiest.

I think my next major thing will be to modify ruby itself because there are things that are missing that I feel could make it even better, but I'm trying to figure out if I can get away with just doing it in a really powerful gem.

[0] Designing for billions of writes per day, JSON API 1.1 + auto linking and pagination, dead simple defaults for controllers, lots of extra methods for better code legibility, etc. I've been thinking of extracting it all out into its own thing but I don't want to deal with the headaches of communicating breaking API changes.

Absolutely. Another 10yr Rails dev here. I believe that rails is untouchable as far is it comes to the ecosystem of gems and getting something quickly built and online, however I’m now moving all future apps to Django/ flask in python to take more advantage of the serverless ecosystem, and all of the data processing libraries out there. I’ll miss you Ruby
I've been doing Rails development since the day it was originally open sourced and while I agree about your sentiments about Ruby, I think Rails is also really starting to really show its age. It was a great leap forward at the time, but we've learned a lot of lessons in the meantime.
(comment deleted)
> Ruby hasn't seen much change in the past couple of years

This is the complete opposite of my experience as a Ruby developer. Ruby performance is starting to get really good!

Performance in Ruby has improved. What people are using Ruby for seems to be constrained to "Rails" and Chef. At least going off the job ads in my area.

Meanwhile, Python, JS, Go, Java jobs run the gamut from webdev, ML, to game programming, and custom BI.

Not saying people aren't using Ruby out there, but 5-6 years ago it was all the rage. Couldn't turn around w/o bumping into a Ruby shop.

It seems to have settled into a Niche of "Rails devs" and Ruby fans using it.

There was a post about this a while ago but that's pretty US-centric.

In Japan there is a lot of attention on Embedded Ruby (hence the performance improvements). 99% of the professional Ruby work that I've done here in NY is not Rails. I've done everything from webdev (Jekyll, Sinatra), ETL work, to systems engineering all in Ruby. I've toyed around with Ruby & SDL but the performance at the time (4 years ago) was not good.

I think OP makes some good points. And missed an opportunity to another one.

The transition from "infatuation" to "grudging resentment" (recognizing the fundamental problems with the approach and how they get in your way) is likely to happen with _any_ platform/framework.

When you the emoter develops more experience with it, and also when _it becomes more mature_. A less mature framework, problems that get in your way -- or legit use cases there's no convenient solution for -- can be explained away as "well, it just hasn't gotten there yet." They're still getting in your way, but you forgive it. Even when the things that were easy in the last framework are hard in the new one -- it's just not there yet, and hey, these _other_ things are easy that used to frustrate me a lot!

But eventually it will be mature, and it will still have problems, including fundamental ones with it's approach that get in your way, and also always including (for something mature) "legacy" problems, where most people now realize some choices could/should have been made differently, but it's too hard to change now (for backwards compat, and just cause so much code has been built up).

Leaving the mature thing you have become good at for the new exciting immature thing (you aren't yet expert enough at to see the flaws in) will provide temporary relief at best. The grass is always greener.

[This does not neccesarily apply to some things that are _just bad_. Things that people are using despite the fact that they are _not_ helping them develop quality software efficiently. Those things should just be left. Ultimately one would like to believe that a mature solution that helps you develop software more efficiently will win out in the end -- we know there are 'political', 'marketing', and other considerations that make this not always true. But I want to draw attention to the fact that we are not good at judging whether a new immature framework/platform/language/ecosystem we have little experience with will actually help us develop quality software more efficiently than the mature thing we are expert with, and know all it's warts.]

I honestly would take a page out of DHH's philosophy and say that's fine. It makes no sense that every tool/app/business has to dominate the landscape. In fact that kind of mentality is quite toxic in the long run. Make new stuff, experiment and see what is out there since popularity does not always correlate with quality. Do not let other people's versions of success come to define your own.
I like Rails and see no need for a new basic web framework.

If we want to reinvent something, I'd say a new e-commerce framework is needed, Spree appears dead in the water and honestly, not that much better than Magento. Then again, with Magento 3's embrace of a REST API, finally we'll get to see a services approach.

But if someone wants to make a robust e-comm framework with Hanami, I'd be happy to evangelize that.

But I think everyone needs to just realize that stacks require massive numbers of developers to do well, and new ideas are going to rightly struggle to find traction against the behemoth.

> Now, here’s the first really controversial point I’m going to make: I don’t believe that simply being better than Rails is enough to displace Rails.

Isn't this the totally uncontroversial Principle of Good Enough: https://en.wikipedia.org/wiki/Principle_of_good_enough

?

Yeah, I had a similar thought. I think the author was being deliberately modest, prepping the reader by getting their guard up for a big assertion and then delivering a relatively unsurprising point.
As a Ruby/Rails dev, the OP makes a good, directionally correct point: "I don’t believe that simply being better than Rails is enough to displace Rails."

However, he's off by a bit. It's going to take another framework to not just be "simply better". This framework will need to be an order of magnitude better to get me to switch from the amazingly productive Rails ecosystem. The framework/language marketplace is crowded and you are going to really need to standout to get any serious adoption to compete. For me, the cost of switching all new development projects to Hanami seems to out-weight the benefits (this also assumes Rails is the correct tool for the job of course, which it often isn't).

That said, a Rails/Hanami/Sinatra framework built on the Crystal language, which looks almost exactly like Ruby but gives you C performance, appears like it might be that order-of-magnitude to 100x game-changer that could get me to switch stacks. [0]

Whether you like him or not, Peter Thiel has some good thoughts when it comes to innovation and I think this argument perfectly encompasses this Rails/Hanami discussion:

"As a good rule of thumb, proprietary technology must be at least 10 times better than its closest substitute in some important dimension to lead to a real monopolistic advantage. Anything less than an order of magnitude better will probably be perceived as a marginal improvement and will be hard to sell, especially in an already crowded market. The clearest way to make a 10x improvement is to invent something completely new."[1]

[0] https://crystal-lang.org/ [1] Zero to One - http://amzn.to/2GaaMP0

I expect to see rails slowly die off over the next decade, with many rails developers moving to either Elixir-based web framework Phoenix or something written in Crystal. There are a few web frameworks in Crystal, but none are fully complete yet. - http://kemalcr.com - http://luckyframework.org - http://amberframework.org
Swift will be more prevalent than Crystal. There are already some serious frameworks available and you get the additional bonus of being able to write Mac and iOS with the language as wel.
The server-side swift ecosystem is incredibly small, and that's by far the most important thing for adoption.

You're not really going to share backend source with your iOS apps, so there's nothing to really gain there. Languages are so homogenized these days that moving between the popular few is pretty simple and requires fairly minimal rampup.

My experience is that people who come to feel about Rails the way he describes in the intro (I went through this exact progression, myself) end up moving on to another stack entirely, typically either Elixir or JS.

My personal shift has been to JS, because you do can everything from front-end to AWS to postgres (via plv8) with it -- it covers the whole stack. And with the advent of ES6, it's just not that bad as a language. It's not great, but it's not the misery it once was, either.

As the author says, Rails is great for starting out. It's great for starting projects, and it's great for starting as a web developer. But I know first-hand the pain of growing and scaling a monolithic Rails app that he speaks of, and for projects that I start from scratch I no longer use it.

> but whatever the volume individually, collectively it adds up to a lot of negativity

Nope. Plenty more people love rails and contribute improvements to it than loath it and bash it.

> the building blocks of a Rails application scale really, really badly as a codebase grows

uh - i slide a slider in heroku. Others add machines behind a load balancer. Shopify does 18000/reqs/sec on rails. The "rails doesn't scale" argument died years ago.

> You find yourself longing for POROs, hating the complexities of ActiveRecord callbacks when dealing with subclasses of models, cursing the way instance variables you set on a base controller somewhere end up being referenced inside view templates

No, I don't. these are all things I like about rails.

> the bitter taste in the mouth that prolonged Rails exposure leads to.

can definitely sense the bitterness...

> Whereas for Rails, the all-consuming vision of what the framework should be requires them to put in, amongst all the goodness, the bad stuff that causes people so much grief in the end.

No idea what this "bad stuff" is.

The author isn't a rails developer, and that's fine. But that doesn't mean rails is broken, or wrong, or bad; despite contrary portrayals. It just mean Rails isn't for them. They make it sound like it's some monster to work with and grow - it's the exact opposite. It's streamlined to be easy to grow and work on; which makes working on it enjoyable.

Nothing in ruby will unseat rails for web frameworks; short of rails stopping development. And personally, I am yet to see a more effective and enjoyable framework; nothing really comes close with the speed and power rails provides; where one developer can deliver their product to all platforms, reusing much of the same views and controllers, delivering changes instantly; it still amazes me.

To be fair, the point about "the building blocks of a Rails application scale really, really badly as a codebase grows" is not about performance, it's about code manageability.

Also, just because more people love Rails than loathe it in no way negates the point that there is a lot of negativity. The two are orthogonal.

> it's about code manageability.

I've worked on plenty of large rails codebases, and many times I can just dive right in and start contributing. Any codebase can grow to be unwieldy, but once you understand rails and other code organization techniques in ruby it's not an issue if you take the time to groom things. Code manageability in rails is a highlight.

> the point that there is a lot of negativity

But there isn't a lot. there are a few people who dislike it, and often their points are just because they prefer something different. It's well tested, performant, and has a large community - and been around for over 10 years.

I've been watching my partner try and build a web app "the Rails way" for the past couple of weeks. The result has been huge amounts of pain any time slightly not-off-the-shelf functionality is desired, especially when Devise or email is involved.

It's supposedly great, otoh, if you're working on a CRUD app with minimal requirements, you're not that big into TDD, or if all the complex stuff in your app actually lives on another service that you can talk to over e.g. RabbitMQ that isn't tied down by Rails.

Can you give real examples? I've always heard this complaint about Rails but have also built a few large apps in it and never felt these problems myself.
I think a lot of the problem comes from Rails ease of setup. You can get Devise working in about 10-20 minutes. Then you want to customize something and it takes an afternoon to figure out. With any other framework that's par for the course. Yet somehow developers expect rails to spoon-feed them the entire way.
A couple of specific issues include that email to multiple users is difficult to get right - googling for it results in a number of weird hacks, with Rails providing nothing itself, and the most obvious mechanism involving a lot of logic in your controllers - and Devise's invitations stuff is very inflexible, making a number of assumptions about what data should be stored (invitation timestamps being the major one). Given that a goal of this specific app is to store as little data as possible, that's unacceptable, and resulted in a fair bit of monkeypatching.

And that seems to be the core of it - monkeypatching things or depending on implementation details seems to be the norm when trying to get Rails and its supporting ecosystem to do something other than what it does by default, and that's difficult to maintain over the long term. And if you can't depend on Rails and co being flexible enough to do what you want, you might as well build on a less-opinionated framework from the start and skip the step of trying to bend Rails into shape.

> if you can't depend on Rails and co being flexible enough to do what you want, you might as well build on a less-opinionated framework from the start and skip the step of trying to bend Rails into shape.

Sending email is one of the things rails does out of the box. ActionMailer is builtin. I myself use mailgun as the provider - it took me 5 minutes going. But there are plenty of ways to do it for what your needs are.

Rails has an opinion on how to do things, but you can do your own thing too. Those opinions it comes with let you ship better code faster, and allow you to focus on the real problems of your project.

But rails, in my 8 years of working every day with it across a multitude of projects, has never been not flexible enough.

> Sending email is one of the things rails does out of the box. ActionMailer is builtin.

Yep. ActionMailer is great at sending email... to one person. Where the logic goes in Rails for sending email to multiple people, nobody has a good answer.

Have you read the official docs?

http://guides.rubyonrails.org/action_mailer_basics.html

2.3.3 Sending Email To Multiple Recipients

It is possible to send email to one or more recipients in one email (e.g., informing all admins of a new signup) by setting the list of emails to the :to key. The list of emails can be an array of email addresses or a single string with the addresses separated by commas.

class AdminMailer < ApplicationMailer

  default to: Proc.new { Admin.pluck(:email) },
          from: 'notification@example.com'

  def new_registration(user)
    @user = user
    mail(subject: "New User Signup: #{@user.email}")
  end
end

The same format can be used to set carbon copy (Cc:) and blind carbon copy (Bcc:) recipients, by using the :cc and :bcc keys respectively.

As for Devise, it's not a part of Rails, and there are a few alternative auth gems you can use, so it's not really a valid criticism of the framework if the thing you don't like isn't in the actual framework.

> It's supposedly great, otoh, if you're working on a CRUD app with minimal requirements, you're not that big into TDD, or if all the complex stuff in your app actually lives on another service

Rails is also great at being a big monolith with complex requirements, complete testing, and doing it all in one codebase.

> especially when Devise or email is involved.

Devise, and some other libraries out there, do things in their own wackadoo way. Sometimes this is fine or even good. Other times, it can be a real WTF. Devise is kinda like that. But once you learn to work with it, it can be effective. and if/when it becomes a pain point, you can bring authentication in-app.

> Rails is also great at being a big monolith with complex requirements, complete testing, and doing it all in one codebase.

I've never seen or heard of a large codebase in Rails that looks like that, unfortunately. But perhaps they do exist and I've just never come across anyone who works on one. All of the large codebases I've heard of amount to big frontends in front of a backend service which handles significant amounts of the logic, leaving the Rails app to be almost-CRUD.

Basecamp, for one. DHH is actually doing some tours of the codebase and talking about tradeoffs made and coding style.

https://www.youtube.com/channel/UCdx5Dk3EWTe2i8YDA7bfl6g

But there are plenty out there; github, shopify, hulu to name a few off the top of my head.

To be fair, I've also done a lot of rescue projects where the previous developers were clearly coming from some other background, and doing things in non-rails ways and causing lots of pain for it.

GitHub is very very far from a monolithic Rails app built "the Rails way". I would doubt that Shopify is either, but I can't say for certain. And Hulu's asset pipelines are very unlikely to be Rails, making it a relatively simple "display a catalogue and take payments" app.
This article really doesn't resonate with me. I'm excited about Hanami, but there are a few considerations that keep me from using it.

First, I'd love to see that there are successful implementations of Hanami for larger "real-life" projects. On github right now the most robust Hanami app I can find is this https://github.com/ossboard-org/ossboard. Which is still a relatively simple app compared to what I tend to work on/with.

Second, a while back developers in the ruby community began advocating that too many libraries/gems were Rails centric - often the gems or libs didn't work at all unless used with Rails, or non-Rails support was an after-thought. In my opinion that message seems to have hit home, and more libraries are for Ruby, not Rails, such as ShrineRB and the whole rom-rb family.

Hanami's ultimate challenge, I feel, will be developing an acceptably robust ecosystem (https://github.com/davydovanton/awesome-hanami) that choosing it over Rails isn't going hurt more than the benefits of choosing Hanami. This is greatly helped by the ruby community making gems and libs for ruby, not Rails.

However, in my current project while there are quite a few gems that aren't tied to Rails, there are also a number of key gems that are. I either have to roll my own or deal with alternatives that would be more work.

Lastly, on the topic of Rails vs Hanami:

In my view the single biggest issue with Rails right now is that the scope and complexity of web applications has grown over the years. Most people are developing medium-large projects with Rails, at least relative to the size of projects Rails was initially designed for, and Rails doesn't really accommodate this. Rails engines are an awkward solution to this problem, but that is the direction Rails pushes you. If you start using engine or namespaces heavily in a rails application you quickly run into friction. You can google and find many articles about how different teams have structured their "modular monoliths". None were easy paths.

Hanami's first win is in addressing this problem. http://hanamirb.org/guides/1.1/projects/selectively-boot-app...

It's easy to forget that most people are just starting out (by definition; most people quit or stop), most people just want to make something, and for that, there's nothing better than rails. I'm in this boat. I just want this thing I thought of and designed to be real, and now after doing Hardtl's tutorial and reading/coding for two days, my thing's basic MVP is real. I've never really done a web app before except for some experiments in Clojure. But I'm not programming it in clojure, a language I like better than Ruby and know a lot better than Ruby, because there's no opinionated framework, there are no models, there's nothing even close to rails and activemodel and all that. I just want to make the thing. That's what most infant-sized things are: babies. And to make the baby you make it in rails and deploy it on heroku. If it sticks, remake it in something else if it really does have scaling problems. But most things don't succeed, and if they do, they probably won't succeed at the scale where it matters at all that they were written in rails. (This is a statistical argument.)
Completely agree. I've tried Java/Spring, Python/Django/Flask, JS/Express/Meteor, Ruby/Rails/Sinatra and Elixir/Phoenix. The only thing I've seen that might rival Rails in productivity is Meteor, but that is relevant mostly if you absolutely need an SPA or some kind of realtime support. Apart from that Rails is the most productive framework, and it's perfect for a solo developer or a small team -- and that goes for both novice and experienced developers. I'm currently looking into Elixir/Phoenix –– and I think it has the potential to become as productive as Rails, but so far the ecosystem is much smaller.
Yeah. Perhaps this is a good metric of ecosystem and developer productivity, and would make for a good extensive blog post: how long does it take to implement users, with password resets and security and everything being just so? With rails, it's, what, an early afternoon with devise and some associated gems? What else has that? Again, not perfect, not tailored, but most people don't wear tailored clothes, and don't need tailored clothes, either. I'll be happy if I get one paying user in a few months when I'm ready to show this thing off. (Edit: I just watched a meteor tutorial doing exactly this and now I feel a pull to remake everything. Jeez.)