Back-end Engineering Articles

I write and talk about backend stuff like Ruby, Ruby On Rails, Databases, Testing, Architecture / Infrastructure / System Design, Cloud, DevOps, Backgroud Jobs, and more...



Differences Between Installers, Package Managers and Dependency Managers

Software tools have different versions over time, which is the natural consequence of the evolution of the software. Each time some bug is solved, a new feature is developed, or a new fancy thing is created inside that library, the creators or maintainers release that new version. These new versions can break old versions; for that reason, we encounter different tags like: 5.2.1 or 3.1.0. In previous blog posts, we talked about this: 

So, once we have this versioning-related stuff clear, let's begin with the Installers.

1- Installers

Here is when we have to clarify other concepts about specific terms and split the synonyms. For example, in theory, an installer is quite different from a package manager. Still, developers often mix both of them, and they're used as synonyms, but it actually means entirely other things.

The installer is a program that can help us to install different versions of a program for the operating system. Of course, when we refer to an operating system, we're talking about the global environment of the system, for instance: Linux, macOS, or Windows. 

So, this means that the installer basically installs software globally in our operating system. But there are other crucial differences: An installer, generally speaking, makes no effort to coordinate its versions with the versions already installed in the machine, so it can get conflicts quickly with other programs without you noticing it and until you try to run the other program. So, it's better to use the installers carefully because they can break programs from your local machine.

Note: It is fair enough to say that Windows tends to use installers more frequently than the other operating systems

Another key difference with installers is that you may automatically get critical updates for the operating system, but a lot of the software installed will require manual intervention to update. This can be painful because installers don't care about the "coordination" of the versions. 

Also, with installers, you can quickly end up with many files and folders installed on your machine. 

This is because most programs come with all the libraries they require in the form of Dynamic-link libraries (DLL's) and such (in Windows systems). 

And finally, if you want to uninstall a library, it is easy to do it with this tool.

2- Package Managers

Meanwhile, when we talk about package managers, we refer to the versions of a given software that depend on other software (also called dependencies), not the operating system. This means that a package manager "does" coordinate installs to prevent package conflicts, as a result of which some installs will fail, to prevent a package conflict that would disable the present install or an earlier one.

Let's make a simple example to clarify these differences:

  • * One thing is to install Ruby 2.3.1 on Linux, macOS, or Windows (using an Installer and doing it globally)
  • * Another thing is to install Ruby On Rails 5.2.1 via the "gem install" command (using a Package Manager to work on a given project).
  • * In this example, the package manager (called with the command "gem install") will coordinate the versions of the packages. In contrast, the ruby installation via the installer will install Ruby. It doesn't matter what.


Package Manager

3- Dependency Managers

Until now, we were talking about compatibility or incompatibility between an isolated tool, like Ruby. However, these tools need to interact with other software and take care of the versions we're connecting to. This is another example:

You use Rails 5.2.1 as a web development framework. You decide to use a gem (the library that does something precisely) like Devise that simplifies the authentication process for the users. So you try to use the devise version 1.0.2. As you can see, we're now dealing with two entirely different tools where each one of them has a different version. That's a big problem because the devise gem needs to match with the Rails version.

Matching different tools with different versions

The keyword here is "Matching." Matching different tools with the correct versions is a big issue to solve, but it can be done with another tool called Dependency Manager. In Ruby, we have Bundler. Bundler is the tool for excellence in the Ruby environment to deal with compatibility between gems. Remember that a gem is a package. 

A package is a set of code that helps us achieve a particular task, like authenticating users or supporting us with Search Engine Optimization (SEO) inside the web project. With Bundler, if we have some incompatibilities, they will let us know for sure because it raises errors almost immediately. But if the different versions match, Bundler will get the suitable versions for us. 

Let's see these examples.

Here we can see how devise 1.0.2 is incompatible with Rails 5.2.1 and Bundler 2.2.20. If we have 2 or more packages that aren't compatible, we'll see that error prompted almost immediately. Let's check the following example.

Here we have the 3 packages compatible with versions. For example, devise 4.6.0 is compatible with Rails 5.2.1 and Bundler 2.2.20. 

Now you can imagine how hard it could be to manage all of this manually. Fortunately, we have RVM, Rbenv, RubyGems, and Bundler. They can help us to achieve all of these goals. 

I think this is enough for installers, package managers, and dependency managers. Our primary concern now is playing with Ruby and having the programming language basics. See you in the next blog post.

Thanks for reading
Daniel Morales.