Over on BlueSky, Gregory Brown suggested a #20daygemchallenge. Post gems you’ve either used time and time again, or have inspired you in some way, in no particular order. Mohit Sindhwani suggested writing about them at the end, which sounded like a great idea!
I’m breaking it into two parts. Here’s my breakdown of my first 10 gems posted:
First is HTTParty: https://github.com/jnunemaker/httparty
HTTPart is the OG http gem. It’s widely used and dead simple. There are a million http options out there, but HTTParty still remains a simple, common option. It sits on top of Net::HTTP
, so it has the same timeout concern as any Net::HTTP
usage. But many Ruby http gems use Net::HTTP
, so that’s not a particular knock against it!
Second is Async: https://github.com/socketry/async
Async is the de facto FiberScheduler for Ruby. That’s what allows Fibers to parallelize blocking operations in Ruby 3+. It’s a great gem and a great ecosystem of tools as well, particularly revolving around all things IO and web protocols.
I talk about it in more detail in my In-Depth Ruby Concurrency talk from RubyConf and I’ll have future articles about it as well.
Third is Pitchfork: https://github.com/Shopify/pitchfork
Pitchfork is an evolution of the Unicorn web server. Its innovation is a forking technique called “Reforking”, where processes are forked multiple times from existing “warm” processes, getting to a point of maximally optimized Copy-on-Write performance.
Like async, I talk about it in more detail in my In-Depth Ruby Concurrency talk from RubyConf and I’ll have future articles about it as well.
Fourth is Ractor TVar: https://github.com/ko1/ractor-tvar
Ractor TVar is an implementation of software transactional memory in Ruby. I learned about it from the Mooro gem, which is a later gem pick. It’s a fascinating and largely unknown library that koichi seemed to have released alongside Ractors and not updated since. I’m very curious to read the source more to better understand how it works and maybe even give it a try in some real code. It only documents examples supporting Ractors but claims to also support threads.
Fifth is Strong Migrations: https://github.com/ankane/strong_migrations
I prefer my database migrations to be stress-free and zero-downtime. The strong migrations gem helps me sleep at night. It detects unsafe operations and blocks them from being run, offering safe alternatives.
There are a few other gems that help keep migrations safe, but I prefer the explicit style of strong migrations. Most other options are a bit “magical”, and will try to rewrite things for you.
Sixth is ZipKit: https://github.com/julik/zip_kit
I’ve mostly used ZipTricks in the past, and ZipKit is the successor to that gem. Being able to stream writes to a zip file is amazing for scaling and ZipKit makes it dead simple.
Using it you can, for instance, stream a file to S3, zipping it on the fly as it’s being uploaded! Streaming is the only way you can reasonably manage operations on very large files, so having this option is critical.
Seventh is Falcon: https://github.com/socketry/falcon
Falcon is a web server based on the FiberScheduler (provided by the async gem). It’s a very scalable server, particularly for IO bound operations. There’s a great talk focusing on it from RailsConf 2023 called Look ma, no jobs.
I also did some benchmarking of its web socket performance compared to a node.js implementation and it is very close in performance!
Here’s the code for it:
https://gist.github.com/jpcamara/8a1a09c9c67347c4e32384b9ce806b70
Like async and pitchfork, I talk about it in more detail in my In-Depth Ruby Concurrency talk from RubyConf and I’ll have future articles about it as well.
Eighth is OJ: https://github.com/ohler55/oj
OJ has historically been the fastest JSON parser in the Ruby world. Usually you can just drop it into a project as a JSON replacement and see things immediately speed up, especially if you are doing any heavy JSON processing.
The JSON gem was recently taken over by the Ruby GitHub organization and byroot has been making some big performance improvements to it - maybe we’ll see parity at some point but OJ is still a great choice.
Ninth is io-event: https://github.com/socketry/io-event
The async gem is the public interface, but io-event is what powers the scheduling at the OS level. It provides all of the integrations with each operating systems kernel event queue: io_uring and epoll for Linux, and kqueue for MacOS. IOCP support for windows is still in progress, so it falls back to a basic Ruby select
there. If you don’t know why any of that is useful, it’s because it’s an important part of keeping the “Reactor” pattern of asynchronous IO efficient.
Like async, pitchfork and falcon (😅), I talk about the reactor pattern in more detail in my In-Depth Ruby Concurrency talk from RubyConf and I’ll have future articles about it as well. I obviously like concurrency 🙂.
Tenth is Glimmer: https://github.com/AndyObtiva/glimmer
I wasn’t familiar with Glimmer but I learned about it at RubyConf. It’s a DSL for building UIs with pure Ruby and has bindings for desktop app ui layers as well as the web. It’s a really cool concept and I look forward to learning more about it by watching How to build basic desktop applications in Ruby. I’ve been working on a cross platform app using React Native and Tauri - maybe I’ll port some of it to Glimmer as an experiment.
After I finish 11 through 20, I’ll post about them as well. Give these gems a try! 👋