Comprehensive guide for building production-quality Ruby gems. Use when creating new gems, structuring gem architecture, implementing configuration patterns, setting up testing, or preparing for publishing. Covers all gem types - libraries, CLI tools, Rails engines, and API clients.
View on GitHubmajesticlabs-dev/majestic-marketplace
majestic-rails
January 24, 2026
Select agents to install to:
npx add-skill https://github.com/majesticlabs-dev/majestic-marketplace/blob/main/plugins/majestic-rails/skills/gem-builder/SKILL.md -a claude-code --skill gem-builderInstallation paths:
.claude/skills/gem-builder/# Gem Builder
## Core Philosophy
- **Minimal dependencies**: Only add gems you truly need
- **Single responsibility**: Each class/module does one thing well
- **Semantic versioning**: Follow SemVer strictly (MAJOR.MINOR.PATCH)
- **Test coverage**: Every public method has tests
- **Documentation**: YARD docs, README, and CHANGELOG
- **Fail fast**: Validate inputs early, raise descriptive errors
## Gem Structure
```
my_gem/
├── lib/
│ ├── my_gem.rb # Main entry point
│ ├── my_gem/
│ │ ├── version.rb # VERSION constant
│ │ ├── config.rb # Configuration class
│ │ ├── errors.rb # Error hierarchy
│ │ └── [feature].rb # Feature modules
├── test/ # Test suite
├── my_gem.gemspec # Gem specification
├── Gemfile # Development dependencies
├── Rakefile # Build tasks
├── README.md # User documentation
├── CHANGELOG.md # Version history
└── LICENSE.txt # License file
```
### Main Entry Point
```ruby
# lib/my_gem.rb
require_relative "my_gem/version"
require_relative "my_gem/config"
require_relative "my_gem/errors"
module MyGem
class << self
def config
@config ||= Config.new
end
def configure
yield(config)
end
def reset_configuration!
@config = nil
end
end
end
```
## Gemspec Best Practices
```ruby
# my_gem.gemspec
require_relative "lib/my_gem/version"
Gem::Specification.new do |spec|
spec.name = "my_gem"
spec.version = MyGem::VERSION
spec.authors = ["Your Name"]
spec.email = ["you@example.com"]
spec.summary = "One-line description"
spec.homepage = "https://github.com/username/my_gem"
spec.license = "MIT"
spec.required_ruby_version = ">= 3.2.0"
spec.metadata["rubygems_mfa_required"] = "true"
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
# Exclude test