---
title: "RubyGems (ruby)"
order: 6
---

A RubyGems [Feed](/docs/proget/feeds/feed-overview) in ProGet acts as a private RubyGems source. RubyGems can be used directly from the Gem client and can also be viewed directly on the ProGet website.

## Prerequisites

Although ProGet was tested with older versions, we recommend using `rubygems 3.0.0` or higher. You can use `gem -v` to see which version of `rubygems` you have installed.

### RubyGems Client Configuration

Before installing packages from ProGet, you should add ProGet to your `gem` installation by using the [`gem sources` command](https://guides.rubygems.org/command-reference/#gem-sources).

```shell
gem sources --add http://«proget-server»/rubygems/«feed-name»
```

If you want to install packages only from ProGet, you'll want to remove other sources. 

```shell
$ gem sources
*** CURRENT SOURCES ***

https://rubygems.org
http://«proget-server»/rubygems/«feed-name»

$ gem sources --remove https://rubygems.org/
https://rubygems.org/ removed from sources
```

Note that these sources are stored in your `~/.gemrc` file.

### Testing Client Configuration

You can use the [`gem search` command](https://guides.rubygems.org/command-reference/#gem-search) to make sure that your client is properly connected to ProGet.

```shell
$ gem search «search-string»
```

This will search all sources configured in your `~/.gemrc` file to be searched. Use the `--source` argument to specify your ProGet server if you have multiple sources configured.

## Installing Ruby Gems

You can use RubyGems from ProGet just like you would use gems from `rubygems.org`. These are generally installed using the [`gem install` command](https://guides.rubygems.org/command-reference/#gem-install):

```shell
$ gem install «package-name» --version «package-version»
```

## Creating and Pushing Ruby Gems

Creating and pushing Ruby Gems to a ProGet feed are performed using the `gem build` and `gem push` commands. 

You can learn about how to create and publish a Ruby Gem to ProGet by reading our guide on [HOWTO: Create and Push RubyGems to a Private Source in ProGet](/docs/proget/feeds/rubygems/howto-ruby-publish).

## Authentication

The first time `gem` needs to authenticate to ProGet (whether for installing or publishing packages), it will prompt for credentials and then store the results in your `~/.gem/credentials` file. You can enter the same username/ password you used to authenticate to ProGet, or a username of `api` and a valid API Key.

You can read more about creating API keys in ProGet on our [API Key](/docs/proget/api/apikeys) page. When creating an API Key you will need to fill in the fields by selecting "Feeds ("Use Certain Feeds)" as the "Feed Type" and selecting your RubyGems feed, and make sure the necessary permission boxes are checked. 

### Authenticating to a Ruby Gems Feed

To authenticate to a Ruby Gems feed from a local Ruby environment requires the feed URL and API key. Add the feed as a source by entering:

```bash
$ gem sources --add http://api:«api-key»@«feed-url
```

For example, authenticating to `http://proget.corp.local/rubygems/public-gems/` using the API key `abc12345` you would enter:

```bash
$ gem sources --add http://api:abc12345@proget.corp.local/rubygems/public-gems/
```

Confirm that it was set by entering:

```bash
$ gem sources list 
```

## Troubleshooting: Bundler & Dependencies

When using a ProGet feed that's connected to rubygems.org, you may notice that running `bundle update` on a gem like [fastlane](https://rubygems.org/gems/fastlane) takes a *preposterous* amount of time and resources. This is because `fastlane` has hundreds of dependencies, and `bundler` needs to download and inspect every single version of every single gem to find if it's a suitable match.

This is ultimately a result of the [dependency API being disabled on RubyGems.org](https://blog.rubygems.org/2023/02/22/dependency-api-deprecation.html) and disabled on ProGet by default.

:::(Info) (TIP: Enable the Dependency API on your Feed)
Enabling the Dependency API will (under Manage Feed) will resolve the issue of "massive gems", but it will be slower for smaller gems. 
:::

The dependency API was the primary way that Bundler fetched dependency info for Gemfile resolution. However, this caused a significant load on the RubyGems.org servers, so a [new API was developed](https://andre.arko.net/2014/03/28/the-new-rubygems-index-format/) and Bundler started using that if available.

Unfortunately, the new API (called the Compact Index API) was only designed with RubyGems.org in mind, and it doesn't work very well with private repositories like ProGet.

### Support for the Compact Index API

The [Compact Index API](https://github.com/rubygems/compact_index) has three endpoints, two of which are supported by ProGet.

<table>
    <tr><td><code>/names</code></td><td> alphabetically-sorted list of gem names</td><td>✅ Supported</td></tr>
    <tr><td><code>/info/gem_name</code></td><td>precedence-sorted list of versions for a gem</td><td>✅ Supported</td></tr>
    <tr><td><code>/versions</code></td><td>tail-appended list of gems published to the library</td><td>🟡 Partially Supported</td></tr>
</table>

The reason that `/versions` is not fully supported is because it's mostly incompatible with the notion of connectors, private packages, etc. It's basically a massive plaintext file (28mb+ and growing every day) that's kind of like the old "dependencies" endpoint. 

Rubygems.org appends new lines to the file (which they store on cloud storage), and these lines may be duplicative of previous data in the file. The Bundler client uses ETags and HTTP Range requests to do "incremental" updates to the file, and then reads it "backwards". 

For users, this means that the first time you run `bundler`, it will download the whole file... and then it only downloads new lines each time. This approach works because RubyGems.org is essentially read-only, and packages cannot be deleted or replaced.

A private repository like ProGet can't really maintain a static text file because we have to aggregate connector data with local packages. Those are both frequently changing/dynamic datasets, and can't be tail-appended static files. And there are also load-balanced servers to consider.

Although ProGet can easily generate this text file on demand,  `bundler` would need to frequently download the whole file. For most use cases, that's slower than downloading (and caching) all of the gems.

Instead, when the Dependencies API is enabled, ProGet will download the `/versions` file from RubyGems.org, process it, and use that to return Dependencies.
