Reading Roundup: Pick Your Dependencies
When to reach for a gem, when to build it yourself, and what to check before you commit to either.
Hey there,
Two of this week’s articles are explicitly about gem selection. The other three are about the same question applied differently: which database holds the truth, how much of your LLM integration to build yourself, and whether your AI tools need to phone home at all. The thread is the same. Be deliberate about what you add to your stack, because everything you add is something you maintain.
Persistent Multiplayer State Without Chaos
Julien Singler on the architecture behind a live multiplayer game: PostgreSQL holds the source of truth, Redis holds derived state that can be rebuilt, and a single SetNX call handles distributed locks for periodic jobs.
LLM Layer for a Rails Application
Dmitry Tsepelev walks through a pattern for wiring LLMs into Rails: a base class with configuration via methods, ERB templates for prompts, a Runner for instrumentation, and a two-level testing strategy that separates request logic from prompt correctness.
https://dmitrytsepelev.dev/llm-layer-in-rails
Running AI Locally for Ruby Development: A Practical Guide
Germán Silva on running LLMs entirely on your own machine with Ollama, Aider, and Continue in VSCode. No API keys, no telemetry, no code leaving your laptop. The trade-off is weaker reasoning on complex tasks, but for boilerplate, test scaffolding, and documentation it holds up well.
https://www.linkedin.com/pulse/running-ai-locally-ruby-development-practical-guide-gim%c3%a9nez-silva-o5vdf/
Cool Down Before You Install: Give New Gems a Few Days to Be Vetted
Bundler 4.0.13 ships a cooldown feature: a time-based filter that refuses to resolve to a gem version until it has been public for at least N days, closing the window that most supply-chain attacks exploit.
https://blog.rubygems.org/2026/06/03/cooldown-let-new-gems-be-vetted.html
How to Choose a Gem Wisely (To Prevent a Maintenance Nightmare)
FastRuby.io on the five factors to check before adding a gem: maintenance activity, community adoption, licensing, security history, and whether the gem is the right size for the job.
https://www.fastruby.io/blog/how-to-choose-a-ruby-gem.html
Quick notes and actionables
The multiplayer state article is a clean example of picking the right store for each type of data: the rule is simple. If Redis disappears, the game is slow but correct. If PostgreSQL disappears, the game is gone. That asymmetry tells you exactly what each store is for. The distributed lock pattern is worth knowing even if you’re not building a game. A short-lived
SetNXwith a TTL equal to the tick interval guarantees exactly one instance runs a periodic job per window. No leader election, no Zookeeper. For per-record mutations,SELECT ... FOR UPDATEinside a transaction is enough. PostgreSQL is good at this and you don’t need to invent a lock manager.The LLM layer post is the kind of Rails architecture piece I’ve been wanting to see: rather than reaching for a framework that handles everything, Dmitry builds a thin layer on top of ruby_llm. Each LLM call gets its own class with methods for model, prompt, instructions, output schema, and response transformation. The prompts live in ERB files next to the request class, just like Rails views. The two-level testing approach is practical: unit tests mock the HTTP connection and run on every commit, prompt tests make real LLM calls and run on a schedule. His point about rich context beating tool use for most Rails tasks matches what I’ve seen in practice. If you know what the LLM needs, pass it explicitly rather than hope the model asks for it.
The local AI article is worth reading if you’ve been curious but haven’t tried it: the honest assessment of where local models fall down (hallucinated function names, incorrect memory ownership assumptions, and invented APIs) is more useful than the success stories. The practical setup is a smaller model (7B) for autocomplete where latency matters, and a larger model (32B) for chat and refactoring. The Git integration in Aider is the standout feature: every accepted change gets committed with a contextual message, which turns your history into a readable audit trail. The supervision loop of request, review, accept, test, and self-correct is a good one.
The Bundler cooldown feature is a genuine step forward for Ruby supply-chain security: most attacks exploit a narrow window between a compromised account pushing a malicious version and developers running
bundle install. Cooldown closes that window by refusing to resolve to a version until it has been public for at least N days. The implementation is smart: it reads the per-versioncreated_attimestamp from rubygems.org’s v2 compact index, and versions from sources that don’t expose timestamps stay resolvable. Addingcooldown: 7to your source line in the Gemfile is the simplest setup. The escape hatch (--cooldown 0) exists for when you need to grab a security patch immediately.The FastRuby.io gem selection post puts the whole decision into a single flowchart: do you really need this functionality? Can you build it in a few lines? If not, does the gem pass checks for maintenance, adoption, licensing, security, and fit? The Mike Perham quote they open with is still the best summary: “Every dependency in your application has the potential to bloat your app, to destabilise your app, to inject odd behaviour via monkeypatching or buggy native code.” Their checklist at the end is worth bookmarking: release in the last year, issues being triaged, multiple contributors, clean
bundle-audit, semantic versioning, and the right size for the job.
From the week
I’ve been thinking about gem selection a lot this week, specifically around authentication. I’ve never been a fan of Devise. It does a lot, but as soon as you need to look into any of it, the complexity ramps up fast. Some of the things it does feel over the top for what most apps actually need.
With the introduction of the Rails authentication generator and the authentication-zero gem, I think there’s even less reason to reach for Devise on a new project. Both give you a clear, readable starting point that you own from day one. You can see every line of code, understand every decision, and change anything without fighting a framework. I always lean towards simplicity over picking a gem, and authentication is probably the clearest example of where that pays off.
On a different note, I took some time off over the past couple of weeks, and it’s done exactly what it needed to. I came back recharged and ready to go. With my renewed energy for AI, I’ve found myself working on several projects at once: a cookbook app, a community management app with a website for my local community, a Shopify store for my local farm shop, and a cleaners directory. All things I can move on quickly now that they’re a bit more established and I’ve got a good flow for using AI. I absolutely love the compound engineering plugin from Every. It’s become a core part of how I work.
Plenty to chew on this week. If you end up building something off the back of any of these, I want to hear about it. P.S. You can see everything I’ve been reading at dcyoung.dev/bookmarks.

