A step-by-step guide to building a Ruby gem from scratch
Tags: ruby
Published: 2024-03-26 07:00:00

*This article was originally written by [Julie Kent](https://www.honeybadger.io/blog/authors/juliekent/) on the [Honeybadger Developer Blog](https://www.honeybadger.io/blog/create-ruby-gem/).*

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-about-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":

```sh
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:

```sh
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):

```sh
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](https://guides.rubygems.org/specification-reference/).

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.)

```ruby
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.

```ruby
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:

```sh
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:

```sh
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](https://rubygems.org/sign_up).
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:

```sh
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](https://bundler.io/guides/creating_gem.html).

## 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](https://guides.rubygems.org/contributing/) to get started!