If you have worked with Ruby or Rails, you have probably heard of or used gems. Gems are libraries that can be used across code bases to provide useful functionality. While seemingly mystical, you can easily create your own gems and publish them for others to use. This article will de-mystify gems and show you how to build your own.

tl;dr

This article discusses how to create a Ruby gem from scratch, without third-party tooling; keep reading to learn the minimum information that Ruby needs to create a new gem. Or—to generate a complete boilerplate Ruby gem fast—you can use Bundler.

What are Ruby gems?

To put it simply, a Ruby "gem" is a self contained Ruby library. The code within these libraries often does something helpful that can easily be integrated into other projects. For example, there are Ruby gems for various purposes, including the following:

  1. Authentication
  2. Debugging
  3. Styling
  4. Integrating with databases
  5. Logging and error handling

Personally, I think whoever came up with the term "gem" deserves a marketing award. It makes gems seem so magical, but don't worry, we will demystify how simple it is to publish your own.

The difference between a Ruby gem and RubyGems

Before we get started with our tutorial on how to create and publish your own gem, I thought it'd be helpful to clarify one thing first. While there are Ruby gems, there is also something called RubyGems; notice the capitalization and lack of a space in the second term. RubyGems is a package manager for Ruby, essentially a tool designed to easily manage the installation of gems, and a server for distributing them. You may not have realized the difference because, since Ruby v1.9, RubyGems has been bundled with the standard Ruby package. However, if you've ever used the command gem in your CLI, then surprise! You have been utilizing RubyGems.

What our gem will do

We'll build a gem to convert a temperature from Celsius to Fahrenheit. Of course, this is simple functionality, but it's also not useless and has enough complexity that you'll gain a solid understanding of the basic building blocks involved in creating a gem.

Set up

First, open your shell of choice and create a new directory with the name of your gem. I'll name mine "julies_temperature_check_gem":

mkdir julies_temperature_check_gem
cd julies_temperature_check_gem

Next, create a subdirectory called "lib"; this is where the code for your package will be installed. The convention is to have one Ruby file with the same name as your gem:

mkdir lib
touch lib/julies_temperature_check_gem.rb

We will also need to create a ".gemspec" file (we'll discuss this in the next section):

touch julies_temperature_check_gem.gemspec

Understanding the .gemspec file

Every gem needs to have a .gemspec file. This file serves as the interface to RubyGems.org, and it houses important information, such as what's in the gem, who made it, and the version. Certain fields are required in every .gemspec file:

  • authors
  • files
  • name
  • summary
  • version

There are also a number of optional fields that you can include in your .gemspec file. The following fields are recommended by RubyGems:

  • description
  • email
  • homepage
  • license
  • licenses
  • metadata
  • required Ruby version

I believe most of these fields are self-explanatory, but if you'd like to learn more about any of the fields above or the additional optional fields that aren't part of the recommended set, you can check them out here.

Let's open our gemspec file in the editor and add the required fields (of course, edit the obvious ones with your name, version, etc.)

Gem::Specification.new do |s|
  s.name        = "julies_temperature_check_gem"
  s.version     = "0.0.0"
  s.summary     = "Converts Celsius to Fahrenheit"
  s.authors     = ["Julie Kent"]
  s.files       = ["lib/julies_temperature_check_gem.rb"]
end

Writing our code

Let's write the code for our gem! Open the Ruby file you created during the set-up process. We'll create a simple class and our method to perform the conversion.

class JuliesTemperatureCheckGem
  def self.convert_temperature(input)
    puts "#{input.to_f * 9 / 5 + 32}"
  end
end

Build and install

Because we have created our gemspec file, we can build a gem from it! All we need to do is run the following:

gem build julies_temperature_check_gem.gemspec

You should see the following output:

gem build julies_temperature_check_gem.gemspec
  Successfully built RubyGem
  Name: julies_temperature_check_gem
  Version: 0.0.0
  File: julies_temperature_check_gem-0.0.0.gem

Cool! Now let's install it! To do so, run the following:

gem install ./julies_temperature_check_gem-0.0.0.gem

You should see the following output:

Successfully installed julies_temperature_check_gem-0.0.0
Parsing documentation for julies_temperature_check_gem-0.0.0
Installing ri documentation for julies_temperature_check_gem-0.0.0
Done installing documentation for julies_temperature_check_gem after 0 seconds
1 gem installed

Testing and publishing

This is the moment of truth! We need to open IRB and see if it works!

irb
3.1.2 :001 > require "julies_temperature_check_gem"
=> true
3.1.2 :002 > JuliesTemperatureCheckGem.convert_temperature(5)
41.0
=> nil

Amazing! We have created our very own gem. If we wanted to, we could publish our gem to RubyGems.org so that others in the Ruby community could use it if desired. Since this is such a simple example, we won't actually this, but the steps are very simple.

  1. First, you need to sign up for a RubyGems account. You can do so here.
  2. Then, from your console, run the following: gem signin You'll be asked to enter your credentials.
  3. Once you are signed in, you just need to push the gem up to RubyGems.org by running gem push julies_temperature_check_gem-0.0.0.gem.

What about Bundler?

One question that might be on your mind is, "What about Bundler?" For those who aren't familiar, Bundler is a tool that helps manage RubyGems dependencies in Ruby libraries. If you've ever worked on a Rails project, chances are you're familiar with Bundler and running commands like bundle install.

You can also use Bundler to write your own gems. It helps speed up the process, as it creates a scaffold directory and initializes a Git repository automatically. To start, all you need to do is run the following:

bundle gem <name of gem>

I highly recommend using Bundler if you want to build your own gem. You can read more about how to use Bundler here.

Wrap-up

Congratulations! You now know what it takes to create a gem and better understand why gems (and RubyGems) are important in the Ruby ecosystem. If you are excited about gems, there are a lot of opportunities to help with open source gems. Here's a good place to get started!

Get the Honeybadger newsletter

Each month we share news, best practices, and stories from the DevOps & monitoring community—exclusively for developers like you.
    author photo
    Julie Kent

    Julie is an engineer at Stitch Fix. In her free time, she likes reading, cooking, and walking her dog.

    More articles by Julie Kent
    An advertisement for Honeybadger that reads 'Turn your logs into events.'

    "Splunk-like querying without having to sell my kidneys? nice"

    That’s a direct quote from someone who just saw Honeybadger Insights. It’s a bit like Papertrail or DataDog—but with just the good parts and a reasonable price tag.

    Best of all, Insights logging is available on our free tier as part of a comprehensive monitoring suite including error tracking, uptime monitoring, status pages, and more.

    Start logging for FREE
    Simple 5-minute setup — No credit card required