Gem-less
Less is more. For dependencies in software (gems/libraries/packages) this is literally the case.
Less is just pasting gem 'something-cool'
into your Gemfile
.
More is that you get a ton of functionality, probably more than you’ll need, out of the box.
But using a dependency can also turn into
- more hacks to circumvent some behavior of the dependency which does not fit your use case,
- more pains when upgrading your framework if your dependency is closely tied with the framework,
- more headache if the dependency gets abandoned.
Understand your application
A dependency could be considered just some external code not included in your own application source code but in my experience it is more than that. To fully understand your application you should also understand your dependencies, to a certain degree. So using large dependencies with large APIs means you either spend a lot of time understanding some external piece of code or that you don’t invest much time and only have little insight into that dependency.
In my opinion we should consider dependencies as part of our own code bases, again to a certain degree. I’m not talking about the standard library, the internals of your web framework or low-level dependencies like database drivers, application servers and tools for development/testing. Introducing a dependency, especially a high-level one, is more than just pasting a line into your Gemfile
; it is somewhat equivalent to including the entire source code of the dependency into your own.
DIY
When I got into Rails around 2011 I was amazed by the “there’s (probably) a gem for that” philosophy. But now I think that using too many gems makes your application harder to understand and reason about. Today I tend to stick with the Rails defaults, which in itself is a major dependency alongside the default gems included in the Gemfile
generated by rails new
. I then primarily pull in dependencies for
- error tracking,
- background processing,
- and official (SaaS) clients (e.g.
stripe
andaws-sdk-s3
)
Regarding the last item, (SaaS) clients, I usually end up creating my own (net/http
based) mini-client
- if there is no official or actively maintained Ruby-gem,
- or if I’m only going to use a few endpoints and authentication can be easily implemented.
Dependencies with built-in UI
Dependencies which dictate a certain UI in terms of routes, controllers and views usually end up needing a lot of customization. Because of my own experience with this I tend to not use these types of Ruby-gems even though Rails engines let you override basically all of it. Either you
- constrain your application to follow the structure of the Ruby-gem,
- or you do custom configuration and override the views and controllers.
The first option is OK in the early stages of your application but can become a problem later on. The second option will make your application harder to understand because now you could be using the dependency in non-standard ways.
Conclusion
Dependencies can be helpful or get in your way. This perception will most likely change with your experience and also when your application itself matures. When a dependency starts to get in the way I would recommend considering “What if I DIY this functionality?” - you’ll learn a lot and get a solution specifically tailored to your needs. And because the source code is right there inside your application source code you’ll ultimately understand it better and be more confident about it.