Podcast Summary: Static Analysis for Ruby with Jake Zimmerman
Podcast: Software Engineering Daily
Episode: Static Analysis for Ruby with Jake Zimmerman
Date: October 14, 2025
Host: Josh Goldberg
Guest: Jake Zimmerman, Lead Developer on Sorbet at Stripe
Main Theme and Overview
This episode delves into Sorbet, Stripe’s open-source static type checker for Ruby, with lead developer Jake Zimmerman. Hosted by Josh Goldberg (TypeScript/JS tooling expert), the conversation explores Sorbet’s origin, technical and architectural challenges of static typing in a dynamic language, key features, performance, collaboration with the Ruby ecosystem, and both present and future of typing in Ruby. The episode offers both a beginner-friendly intro to Sorbet and plenty of deep technical dives for advanced listeners.
Key Discussion Points & Insights
1. Jake’s Background and Early Motivation
- How Jake Got Into Tech:
Jake traces his interest in software back to a seventh-grade computer science elective ([02:03]). - Teaching Experience and Onboarding:
Motivation for Sorbet and onboarding new engineers at Stripe borrows from his experience as a college teaching assistant:"If you can use some of the whimsy that you might have developed as a teaching assistant...maybe the people remember the onboarding material a little bit better."
— Jake ([02:36])
2. Introducing Sorbet to New Engineers
- First Day Pitch:
Sorbet checks your Ruby code for type errors, flags them, helps with navigation/autocomplete, and acts as a productivity tool ([03:29]). - Deeper Pitch:
For experienced engineers, Sorbet’s type system is a robust tool for catching bugs and reasoning about code structure ([03:29]).
3. The Need for Static Analysis in Ruby
- Dynamic Languages’ Flexibility and Issue:
Ruby’s flexibility leads to code that’s difficult to reason about, hence the need for a type checker ([04:51]). - Example Motivation:
Not knowing if a function argument is an object or an ID is a key pain point solved by types ([04:51]).
4. Metaprogramming and Dynamic Patterns in Ruby
- The Challenge:
Ruby’s culture of extreme metaprogramming makes static analysis hard. Sorbet offers partial support but can’t cover all cases, and adding a type checker curtails certain dynamic patterns, which may be a beneficial tradeoff for large teams ([06:21]):"If the reason why you really like Ruby is because of all this flexibility...adding a type checker might just be a strict loss for you...But, the selling point...is that those sorts of programming patterns tend to be extremely confusing and hard to teach."
— Jake ([06:21])
5. Sorbet Project History & Lessons
- Origins:
Born out of strong internal demand at Stripe in 2017, Sorbet was developed due to the lack of suitable alternatives ([08:27]).
6. Advanced Type System Features
- Modeling Metaprogramming:
Sorbet supports Ruby’s classes-as-values paradigm via clever use of generics ([09:50]). - Retrofit to Ruby’s VM:
Challenge in modeling Ruby’s runtime semantics statically, e.g., 'private' methods aren’t truly private ([11:46]):"No one really ever thought about the static semantics of these language features..."
— Jake ([11:46])
7. Sorbet’s Architecture
- Core Pipeline:
Sorbet is written in C for performance. It parses Ruby code to an AST (Abstract Syntax Tree), then compiles that to a control flow graph for type checking with flow-sensitive typing ([12:39], [14:30]). - Why C and not Ruby?:
For performance, memory control, and team experience, especially for Stripe’s large code base ([15:43])."The actual computational complexity is not...what drowns a type checker. It’s whether you have too many spurious allocations..."
— Jake ([15:43])
8. Performance and Scaling Challenges
- Previous Strategy:
Heavy micro-optimizations, reading the entire codebase into memory (~20GB), but scaling limits are looming ([20:28]). - Ongoing Re-architecture:
Moving towards analyzing only dependency-based code subsets at a time ([20:28])."We fundamentally cannot read 100% of the code base anymore. We need to figure out a way to make it only read a subset..."
— Jake ([22:55])
9. Explicit Dependencies & Community Practices
- Combatting Ruby’s Implicitness:
Making dependencies explicit is crucial as Ruby allows implicit/hidden dependency flows ([23:17]). - Ruby Features Stripe Disallows:
For example, Stripe bans dynamic constant lookup to avoid untraceable dependencies ([24:30]).
10. Collaboration & Ecosystem Impact
- Working with Ruby Core Team:
Meetings every few months to advance the typing ecosystem (esp. RBS, the Ruby standard for type annotations) ([25:43]). - Shopify Collaboration:
Sharing innovations and ensuring type system improvements suit large codebases ([25:43]).
11. Upcoming and Desired Features
- Ecosystem and Syntax Improvements:
Big push for more palatable type annotation syntax ([26:56]). - Closing Type System Gaps:
Fixing poor interaction between structs/records and interfaces (finally being addressed after years, affects thousands of files at Stripe) ([29:27]). - Shapes and Tuples:
Bringing richer type support akin to TypeScript object types ([29:27], [32:34]).
12. Community and Ecosystem Support
- Gaps Acknowledged:
Lack of support for publishing gem type definitions outside Stripe, e.g., issues declaring generics in RBI (Ruby Interface) files ([33:39]). - Desire for Increased Community Focus:
Jake aims to address these now that core scaling work is stabilizing ([33:39]).
13. Measuring Code Quality and Type Coverage
- Custom Metrics:
Code quality and productivity metrics are best tailored per codebase, not standardized ([35:50]):"Each individual code base can craft a metric for what productivity looks like...which is something I believe is basically the only way to do it."
— Jake ([35:50])
Memorable Quotes and Notable Moments
-
On Type Safety vs. Flexibility:
"If the reason why you really like Ruby is because all of this flexibility...adding a type checker might just be a strict loss for you..."
— Jake Zimmerman ([06:21]) -
On Choosing C:
"The actual computational complexity is not...what drowns a type checker. It’s whether you have too many spurious allocations..."
— Jake Zimmerman ([15:43]) -
On Scaling Problems:
"We fundamentally cannot read 100% of the code base anymore. We need to figure out a way to make it only read a subset..."
— Jake Zimmerman ([22:55]) -
On Custom Quality Metrics:
"...the way to measure these things is hyperlocal and hyper specific to individual projects..."
— Jake Zimmerman ([35:50])
Technical Deep Dives
Sorbet’s Type System Features (Lightning Round)
- Union Types:
Useful for expressing a method that can return one of several possible values (especially for errors/failure conditions), prevents over-reliance on untracked exceptions ([38:13], [39:06]). - Branded/Opaque Types:
Concealing implementation details; public interface only exposes limited operations (e.g., UNIX file pointers) ([41:15]). - Interfaces and Abstract Methods:
Underused in Ruby, not just for multiple implementations but for data hiding/information encapsulation even with a single implementation ([42:26]).
Community, Usability, and Future Work
-
Promised Improvements:
- Palatable annotation syntax
- Closing long-standing feature gaps (structs/records vs interfaces, shapes, tuples)
- Better external gem type declaration workflows
-
Call to Action:
Join the Sorbet community Slack for discussion and support ([46:15]).
Personal Note/Outro
- Jake’s STP Bike Ride Experience:
Seattle-to-Portland (207 miles); found the ride left him blissful and mentally refreshed—no work thoughts at all ([44:07]).
Timestamps for Key Segments
- Jake's Background & Onboarding Philosophy: [02:03] – [03:10]
- What is Sorbet (Beginner & Advanced): [03:29] – [04:37]
- Ruby’s Dynamic Patterns & Sorbet's Limitations: [05:58] – [08:20]
- Sorbet’s Origins and Stripe’s Decision: [08:27] – [09:33]
- Sorbet Type System Details: [09:50] – [11:46]
- Sorbet Architecture: C, AST, CFG: [12:30] – [15:19]
- Performance & Scaling: [20:28] – [24:20]
- Working with Ruby Core/Shopify: [25:43] – [26:43]
- Upcoming Features & Ecosystem Needs: [29:27] – [35:38]
- Measuring Code Quality: [35:50] – [37:28]
- Lightning Round—Type System Features: [38:09] – [43:28]
- Personal Note—STP Ride: [44:07] – [45:42]
- Community Call to Action: [46:15]
For More Info
- Sorbet: sorbet.org
- Join the Community: sorbet.org/slack
- Follow Jake: Through Sorbet channels
This episode is essential listening for Rubyists considering adding static typing, for those scaling dynamic codebases, and for anyone curious about type checker implementation and ecosystem integration.
