New webinar: "The Remote Job Search: My Microverse Journey" with graduate Paul Rail
Watch Now

We have launched an English school for software developers. Practice speaking and lose your fear.


This article was written by Microverse student, Daniel Laloush. Header photo by .

Introduction to Gems

Gemfiles are an incredibly useful tool for developers but people often misunderstand the usage of the version control environment that a Gemfile provides, due to its syntax. For us to thoroughly understand what a Gemfile is, we need to understand two main concepts. The first is knowing what RubyGem is, and the second is knowing what Gemspec is. 

RubyGem, or Gem as it more commonly is known, is essentially a package manager for the Ruby programming languages (same as Yarn or NPM are for nodes) that provides a standard distribution for Ruby programs and libraries. 

Gemspec is the Readme for gems. It tells you about the author, version, summary, description, internal dependencies, execution - pretty much everything about the gem.

You can find more useful information about these topics here.

Now that we know this, let’s jump in.

What is a Gemfile? 

A Gemfile is a file we create that contains a list of gems we need in order to run a program. 

Let’s dive into what this means though.  

When we start developing a program, we use different gems to allow us to run the program, and sometimes we end up integrating programs for different features in our code. An issue appears when we want to share our program. We need to make sure that any environment that will execute the program has the necessary gems to run it, and this depends on each environment. 

The Gemfile can divide our code into many different sections. It is well known that when a developer starts building a program, he may use many different tools for testing and developing it, to ensure it will behave properly. Sometimes, tools are not needed under the production line, and that’s when the Gemfile kicks in and helps us divide our gems into different sections. For that, we can use two different syntaxes; the first is inline and the second consists of grouping them inside a block of code. You can visualize the latter below: 

{% code-block language="js" %}
gem('sqlite3', :group => [development, test])
# Or
Group :development do 
{% code-block-end %}

Now that we have listed many gems in our Gemfile, we need to know how to install it. That is when Bundler kicks in. Bundler helps us manage the application’s dependencies through its entire life, across many machines, systematically and repeatedly. 

Image from bundler.io

When running Bundler, it downloads the newest version of each gem and installs it for testing, production, development, and even staging, according to our Gemfile. But it’s not always best for us to download and install the latest version. So, we need to keep track of which version the gem is running to avoid inconsistencies and bugs in our code. 

This is why bundler generates a lock file; a file that contains all information regarding the currently installed version of each gem. The lock file helps us keep track of the latest version that was installed. This is important as running different versions can break our code. 

When a Gemfile.lock exists in our root directory, the bundler will ignore all gems that are listed in the Gemfile that already exists in the lock file. Essentially, this means it will only update the lock file with the gems that are not already listed in our Gemfile.lock. Additionally, all gems that are listed will be installed with the version specified in the lock file.  

Furthermore, sometimes, when we develop a piece of the program, we want to use an older version of the gem. To achieve that, we need to explicitly tell our Gemfile which version of the gem we would like to install. This is where our Gemfile can get a little messy.  

Gem Versions 

The Gemfile enables us to explicitly tell the bundler which version to run on. Below, I cover three of the most common methods used to specify the version needed to install. 

  1. The first method is to explicitly write the version we want, by simply writing it down as follow: 

{% code-block language="js" %}
gem('rails',  '')
{% code-block-end %}

  1. The second method is to use the comparison operators, so we can install any version, newer, older, newer equal and even older equal as follows: 

{% code-block language="js" %}
gem('rails',  '>')
gem('rails',  '>=')
gem('rails',  '<')
gem('rails',  '<=')
{% code-block-end %}

  1. Finally, the third version, which is using the ‘Similar to’ (~) symbol. This tells the bundler to install the same version, allowing it to update the last digit. For example, let’s suppose we are running Rails on version and we want to keep it that way, but we’d like to allow our bundler to update the current version of Rails to In that case, we would write it as follows: 

{% code-block language="js" %}
gem('rails',  '~>')
{% code-block-end %}

In Conclusion 

A Gemfile helps us install all the dependencies under a version-controlled environment. This is needed for each group as it can make our lives much easier.  

Say, for example, we want to develop a Rails application that would eventually run on Heroku with a PostGrade server. However, we do not want nor need to install that server in our development machine, so for development, we prefer to use the SQLite server. This server requires little to no configuration to run in our development machine so we can specify when and where we want to install the gem;

{% code-block language="js" %}
gem('sqlite3', :group => [development, test])
gem('pg', :group => production)
{% code-block-end %}

This provides the libraries and dependencies needed for the SQLite Server under our development and test unit, and - when we want to deploy it - will set it up under a PostGrade Server. As you can see, this is helpful because it lets us set a more friendly and flexible environment for developing the application, while enabling us to maintain all the benefits of a PostGrade server under Production.

Learn more about Microverse, and joining our supportive community of remote software developers. Get started below!

Learn more about the author and connect with Daniel on Twitter, LinkedIn, or through his website.

We have launched an English school for software developers. Practice speaking and lose your fear.

Subscribe to our Newsletter

Get Our Insights in Your Inbox

Career advice, the latest coding trends and languages, and insights on how to land a remote job in tech, straight to your inbox.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
We use own and third party cookies to; provide essential functionality, analyze website usages, personalize content, improve website security, support third-party integrations and/or for marketing and advertising purposes.

By using our website, you consent to the use of these cookies as described above. You can get more information, or learn how to change the settings, in our Cookies Policy. However, please note that disabling certain cookies may impact the functionality and user experience of our website.

You can accept all cookies by clicking the "Accept" button or configure them or refuse their use by clicking HERE.