Rails app/lib Must Go

Posted on Jul 28, 2023

It seems pretty common to add an app/lib directory to Rails applications. Even ChatGPT recommended it as a place to put all of the code that does not fit within Rails’ default directories. It’s a bad idea. Not the kind of bad idea that’s going to make your app unexpectedly not work, but the kind of bad idea that’s going to make your app a lot harder to understand and navigate, particularly at scale.

Rails is a convention based framework. There are conventions it follows around structure and naming that enable it to connect all your code without a lot of configuration. This is why imports are not required for anything within the app/ directory, unlike in standard Rails.

So what is the convention of app/lib? It is used for whatever doesn’t fit into the other parts of the app/ directory, there is no convention. It is a dumping ground. I have been deconstructing an app/lib directory recently and converted the code to concerns, models, services and standard ruby code in the top level lib directory.

Practically what’s the problem, though? I can just search for whatever class name I’m looking for in the codebase and I’m all set. No need for the overhead of imports to tell me where it is. The problem is that over time things that belong in default Rails objects just end up in app/lib and the codebase gets harder to understand. More obviously, since lib is a default directory that ships with Rails it gets confusing to figure out what code is in lib versus app/lib. “Are you talking about lib, or app/lib”?

If you are writing code that doesn’t fit anywhere in the standard Rails directories try writing Ruby in lib. If you only know Rails and can’t deal with imports please name your dumping ground within app something other than lib.