Boilerplate for New Gems

Starting Every New Gem the Same Way

Creating a new Ruby gem should be exciting. There's usually an idea you're eager to explore or a problem you're ready to solve. But over the years, I've noticed that the first half hour of every new project looked remarkably similar. Before I could start building anything interesting, I always found myself making the same changes and adding the same tools. Eventually, I decided it was time to stop repeating myself.

The Problem with Fresh Projects

Ruby's generators provide an excellent starting point.

But they intentionally remain fairly minimal.

Almost immediately after creating a new gem or Rails engine, I found myself adding:

  • RSpec
  • SimpleCov
  • RuboCop
  • Bundler Audit
  • GitHub Actions
  • Release scripts
  • CHANGELOG files
  • CI workflows

Then I'd spend time tweaking configuration files to match my preferences.

None of these steps were difficult.

But they were repetitive.

And perhaps more importantly, they distracted from the real goal:

Building the project itself.


Everyone Has Their Own Defaults

After building enough gems and engines, most developers develop opinions.

Not necessarily because one approach is universally correct, but because consistency matters.

Over time, I realized that every new project I created eventually converged toward the same setup.

I wanted:

  • The same test framework.
  • The same coverage tools.
  • The same CI pipelines.
  • The same release process.
  • The same project structure.

If I was always making the same changes, why not automate them?


Introducing My Gem & Engine Setup Scripts

These scripts provide opinionated scaffolding for Ruby gems and Rails engines.

Rather than starting from a blank slate and reapplying the same preferences manually, they generate projects that already reflect the way I like to work.

That includes sensible defaults for:

  • Testing.
  • Linting.
  • Code coverage.
  • Security checks.
  • CI/CD.
  • Releases.

The goal wasn't to replace Ruby's generators.

It was to eliminate the repetitive work that happens immediately afterward.


Getting Started

Creating a new gem is straightforward:

./setup_gem.sh my_gem

Or for a Rails engine:

./setup_engine.sh my_engine

The scripts remember common settings such as the base directory and GitHub username, making subsequent projects even faster to create.

The result is a project that feels ready to work on from the start.


Consistency Matters

One thing I've come to appreciate is that consistency compounds over time.

When every project shares similar tooling and workflows:

  • Switching between repositories becomes easier.
  • CI behaves predictably.
  • Releases follow the same process.
  • Contributors encounter fewer surprises.
  • Maintenance becomes simpler.

The benefits are small individually, but together they remove a surprising amount of friction.


Opinionated by Design

These scripts aren't trying to satisfy every possible workflow.

In fact, they're intentionally opinionated.

They're based on the simple observation that:

I always ended up making the same changes anyway.

Rather than repeatedly customizing newly generated projects, I wanted those preferences baked in from the beginning.

That means spending less time configuring and more time building.


Why I Built It

I wasn't trying to create another framework.

I just wanted to stop spending the first thirty minutes of every project doing the exact same thing.

I wanted new gems and engines to begin with:

  • Testing already configured.
  • CI already in place.
  • Release workflows already prepared.
  • Sensible defaults already established.

Because after generating enough projects, I realized something:

The best boilerplate is the boilerplate you never have to think about.

And sometimes the easiest way to avoid repeating yourself is to automate your own opinions.