Transcript

XO Ruby San Diego 2025 - What I Talk About When I Talk About Ruby by Tim Riley

From Confreaks · Episode page · Watch on YouTube

· 50 min · 8,544 words · 66 timestamped sections

This is the full, timestamped transcript of "XO Ruby San Diego 2025 - What I Talk About When I Talk About Ruby by Tim Riley", an episode of Confreaks published January 10, 2026 (50 min, about 8,544 words). It mentions 20 people, works and ideas, including Hanami, Haruki Murakami, Ruby, Hanekai, Hanekai.

What is discussed, and when

  1. – 5:00: Haruki Murakami, Exor Ruby, Hanami, Sputnik Sweetheart
  2. – 10:00: Hanami, Elixir, Haruki Murakami
  3. – 15:00: Hanami, Haruki Murakami
  4. – 20:00: Hanami, Haruki Murakami
  5. – 25:00: Hanami
  6. – 30:00: Hanami, Haruki Murakami
  7. – 35:00: Hanami, Shrine, Haruki Murakami, Rodoth
  8. – 40:00: Hanami, Hanekai, Hanekai, Elixir
  9. – 45:00: Haruki Murakami, Hanekai, Hanekai, App Signal
  10. – 50:00: Hanekai, Hanekai, Haruki Murakami, Hanami

Notable quotes from "XO Ruby San Diego 2025 - What I Talk About When I Talk About Ruby by Tim Riley"

  • Well, yeah. Thanks, Jim and thanks Exor Ruby for giving me this opportunity.
    about Exor Ruby · at
  • And guided by someone special. Our guide is the author of those very words, Japanese novelist Herukqi Murakami. And before we set off, let's just get to know him a little bit.…
    about Haruki Murakami · at
  • And here is what Ruby open source looks like for me today. I lead these three projects. We have Hanami, a complete app framework, dry, a collection of libraries solving common…
    about Hanami · at
  • Time in 2015, it was popular for Rubious to go and leave for languages like elixir. They were new and shiny. But I didn't want to do that. I wanted to stay with Ruby because I…
    about Elixir · at
  • And next we have Shrine by Yanko Marinich. And this is a Ruby gem for handling file uploads. Now Rails developers here are possibly working with older gems like carrywave or.
    about Shrine · at
  • Now, in the Hanekai name, we're continuing with the spirit of nature and community from Hanami. In Japanese, the hanekai loosely translates into a party of flowers. And with Hanekai, we're.
    about Hanekai · at
  • Thanks to these amazing founding patrons. So, thank you to Sidekick, Honeybadger, Fast Ruby, App Signal, and Ruby's very own Brandon Weaver. And we really love to see you and…
    about App Signal · at

Who and what is mentioned in this episode?

People

  • Haruki Murakami — Person · 20 mentions · first at
  • Brandon Weaver — Person · 1 mention · first at
    Patrons. So, thank you to Sidekick, Honeybadger, Fast Ruby, App Signal, and Ruby's very own Brandon Weaver. And we really love to see you and your businesses. Join them as…
  • Killbilly Jim — Person · 1 mention

Books & papers

  • Sputnik Sweetheart — Book · 1 mention · first at
    So, it goes in the novel Sputnik Sweetheart. That's a story of love, of distance, and the spaces between souls.
  • What I Talk About When I Talk About Running — Book · 1 mention · first at
    Running is so core to Murakami's identity that it became the overarching theme to his memoir. He called it what I talk about when I talk about running.

Companies & orgs

  • Hanekai — Company · 7 mentions · first at
    Now, in the Hanekai name, we're continuing with the spirit of nature and community from Hanami. In Japanese, the hanekai loosely translates into a party of flowers. And with Hanekai, we're.
  • Exor Ruby — Company · 2 mentions · first at
  • App Signal — Company · 1 mention · first at
  • Fast Ruby — Company · 1 mention · first at
    Thanks to these amazing founding patrons. So, thank you to Sidekick, Honeybadger, Fast Ruby, App Signal, and Ruby's very own Brandon Weaver. And we really love to see you and…
  • Honeybadger — Company · 1 mention · first at
    Thanks to these amazing founding patrons. So, thank you to Sidekick, Honeybadger, Fast Ruby, App Signal, and Ruby's very own Brandon Weaver. And we really love to see you and…

Products & tech

  • Hanami — Product · 42 mentions · first at
  • Hanekai — Product · 7 mentions · first at
  • Shrine — Product · 4 mentions · first at
  • dry — Product · 3 mentions
  • ROM — Product · 3 mentions
  • Rodoth — Product · 1 mention · first at
    Examples to follow. The first is Road again from Jeremy Evans. Jeremy calls Rodoth Ruby's most advanced authentication framework. And like Jere everything Jeremy says, I'm…
  • Flex — Product · 1 mention
  • ROA — Product · 1 mention

Concepts & topics

  • Ruby — Concept · 12 mentions
  • Elixir — Concept · 2 mentions · first at

Full transcript with timestamps

Well, yeah. Thanks, Jim and thanks Exor Ruby for giving me this opportunity. It's really cool to to beam into San Diego. Uh, I hope it's been a great day. Uh, thank you all for bearing with a remote talk. I know these are always a little a little bit different to the inerson experience, but yeah, I really appreciate the chance to be here. So, let's just let's just dive in. No mistake about it. Ice is cold, roses are red, I'm in love, and this love is about to carry me off somewhere. So, it goes in the novel Sputnik Sweetheart. That's a story of love, of distance, and the spaces between souls.

Friends, today I want to tell you a love story of my own of a love for Ruby and a love that carried me off somewhere. Today we'll go on that journey together and guided by someone special. Our guide is the author of those very words, Japanese novelist Herukqi Murakami. And before we set off, let's just get to know him a little bit. Now, some of you may already be aware of Murakami already from one of his more than 20 published novels. He's been a writer since 1979 and he's the most widely read Japanese novelist of his generation and his works been translated into over 50 languages.

And across all his books, Murakami's writing blends the surreal with the everyday. These are quiet, strange stories where the real action isn't what happens, but how it changes you. These are stories that kind of sneak up on you emotionally. Now, as I've read Murakami, what snuck up on me the most was not one of his works of fiction, but rather his memoir, where he shares his passion for long-distance running and its parallels with his life as a writer. When I read this book, what struck me was just how open and plain speaking Murakami was throughout it. Here he was, this literary giant here writing without pretense, showing us his own flawed humanity through his very personal account of the ups and downs of his running and writing across the decades.

And it has been many decades. Morakami's been long-distance running almost as long as he's been a writer. He started the hobby in 1982 uh when he decided to go full-time as a writer. and he's not stopped since. 40 years have gone by. Murakami still runs every day and he's run a marathon at least once in every year. Running is so core to Murakami's identity that it became the overarching theme to his memoir. He called it what I talk about when I talk about running. And today I'll follow in his spirit and I want to share what I talk about when I talk about Ruby. You see, this memoir was so inspiring to me that I wanted to echo its format. I want to share some of my story to speak to you as plainly and as personally as I can. And as I go, I'll share some parallels that I found striking between the story Murakami shared about his life and and the one that I've been living in Ruby open source.

And here is what Ruby open source looks like for me today. I lead these three projects. We have Hanami, a complete app framework, dry, a collection of libraries solving common tasks, and ROM, a powerful and flexible persistence toolkit. Now, if you've seen any of these before, it's likely because you've chosen to venture outside of the Ruby and Rails mainstream. And it's true. I think it's fair to say these tools are countercultural. And much of that is by design because my teammates and I built these because we felt the need for something different within Ruby. And then as we shared these over the years, we certainly met resistance. And here was where I was struck by one aspect of Morakami's life, which is this man who's been called one of the world's greatest living novelists could also have his work roundly criticized at the same time. Because while Murakami attracted a great many readers and fans in Japan,

the Japanese literary establishment on the other hand, the critics and other writers, they would call out his work as being unJapanese. And that would lead to Murakami at one point calling himself a black sheep in the Japanese literary world. Now, as someone building Ruby tools that push up against the status quo, this black sheep feeling really hit me. And when I look back, I realized I've been a Ruby black sheep for 10 years now. From the moment I started building these tools back in 2015, those 10 years ago, I had reached a point of stagnation personally as a Rails developer. I could tell I was no longer growing and learning in the way that I wanted. The Ruby I had been writing no longer felt right for me. I knew I needed some kind of change to reach that ne next level and unlock that new journey of learning. Now at this time in 2015, it was popular for Rubious to go and leave for languages like

elixir. They were new and shiny. But I didn't want to do that. I wanted to stay with Ruby because I love Ruby. And yes, this is the love story I promised you at the beginning. You see, I got lucky and I found Ruby all the way back in 2002 and I've been using it ever since. So, I loved Ruby and I didn't want to leave. What I did instead then was look around for the other black sheep out in the Ruby world to see what they were doing and to see if it was something I could join in on. And this is what changed my world. This is what carried me off somewhere. What I found in those other black sheep were the seeds of what has become after 10 years of work the Hanami Dry and ROM projects we have today.

And today we'll look at where we can go from here. And in proper memoir style, I'm going to split this up into chapters. In chapter one, I'll share what you need to know to become a running Hanami developer. In chapter two, we'll look at the evolution Hanami might bring to Ruby and why I think it's essential. And then in chapter 3, I share what I'm trying to do to make all of that happen. So, let's get started. Let's lace up our shoes, follow in Murakami's footsteps, and hit the road. It is time for us to run a race.

And learning Hanami will be the race that we run today, a race towards a different style of Ruby. And on the topic of starting races, Murakami writes, "The first few miles are always a test. I'm nervous, but I know that if I just keep moving forward, I'll settle into a rhythm. I always do." Today we're going to see some Ruby that might look unfamiliar to you and I know this can be its own kind of test, but don't worry. I know that you'll move forward and together we'll settle into our own rhythm here as well. So, let's do it. Let's install Hanami and then run Hanami new to create a new app. And today we'll call our app Bookshop. And then we can hop inside our app and run Hanami Dev to start our development server.

And here we're greeted by this lovely welcome screen giving us access to everything we need to learn how to get started with our app. Now from here we can hop over into the code and check out the app class itself. And this is nice and simple. We won't need to spend too long here. But there is one thing to point out and it's that all app code in Hanami lives inside a single name space matching the app's namespace. So here we have module bookshop. This is the module all our code will live within. Now from here we can move to the routes and here we see we have the first step we need to take to make our app real we need to add a route and to do this we can generate an action and Hanami gives us a friendly generator we can run to do this. So for our bookshop let's make an action for our products index and back in the routes we see that it's given this route to us and this looks straightforward. A get to products will

take us through to our index action. And here's the action class our generator made. Now, the thing to know about actions in Hanami is that they're the pieces of our app responsible for all our HTTP interactions. And we have exactly one action class per endpoint. And it's this handle method where we put all of our actions logic, the dealing with the request and response objects that we're given. But for now, this starter action is already enough because by default, it matches it renders a matching view. And here's that view.

Now, just like actions, every view in Hanami comes with its own class. And the job of the view class is to prepare exposures. These expose the values that we want to use inside the views templates. So for this case, for a products index view, we'll want an array of products. But where do we put that logic? the job of fetching the products from our database. Well, to do this, we can get to know one of Hanami's most important features, and that is in Hanami, our app is also a container. And the container here works as a central organizing object that's responsible for loading and managing access to all the components in our app.

Our view is already a component, and we can fetch it from the app like this, using a key that matches its name. Then what we get back is an instance of that view readym made and ready for us to use. In fact any class that we put into app will be made available as a component. So in our case we can go ahead and make a component for a product repo. This can be the thing that returns the products to our view. And once again we have a generator that can help us do this. [snorts] And this is how our repo looks. Inside we can add a method to find and return the latest products from our database. And here we're working with a full powered API that will let us construct every query to our liking.

So now we have two components. We have our view and we have our repo. But how do we get them to know about each other? What we really want to do is use this repo inside our view. Well, for this we can use Hanami's depths mixin. We can include this mixin inside any class in a hanami app whether it's a a framework provided class or not and then pass a list of components we want to make available as dependencies deps here being our shorthand for dependencies and those components then become available as instance methods that we can use wherever we need in our classes.

Now what we're seeing here is classical dependency injection a long long-held object-oriented technique but here we've made it easy and low friction and using depths like this is central to how we can create highle behavior by bringing together a range of smaller more focused components and in this case it's enough for us to now go and expose the latest products from our repo and make them available to our template where we can use them as we need to prepare our views HTML. So with that done, we can hop over back to our Hanami server and then make a request to our server and see our products have come back as HTML. So well done everybody. We've just made our first working feature with Hanami.

And what this means is that we're now fully into this race. And here Murakami would write after running for a while your muscles sort of forget what they're doing. You don't have to think. You just become the act of running. So let's become the act of building our app and learn a few more Hanami features. And we can start by looking at the testing experience. How can we test this view we just created? Well, like every part of Hanami, views are designed to be directly testable. We can call new directly on our view class and even pass in a test double for that product repo dependency. This will let us control its behavior for the purposes of that test.

And that's enough already for us to go ahead call the view and test that its output meets our expectations. What we're seeing here is a a low-level isolated unit test. And for most views or actions, we won't need to go this far. A more helpful approach would be to make an integrated end-to-end test, something that calls our app from the outside, like a feature spec. And these are available for you in every new Hanami app. But the thing to take away here is that because all Hanami objects are designed to be directly testable just like this. It means we as the app authors get to make the best testing choice for each situation.

So we've interacted with our code through tests. We can also do so in the console. Once we launch the console, we can use this app shortcut to get to our app. And from there, we can come back and uh access our components which are given to us as instances ready for us to use. Now, one component that Hanami gives us by default are our settings. These are the values that we give our app to help it run correctly in each environment. Things like keys, secrets, and flags. We can declare our settings here in this config settings file. Say we want to send emails when new products are created. And to do this, we want to use a third party email service. Well, here we can create a setting for its API key.

And we can also declare that settings type. And this will mean our app will never boot into an unpredictable state. These settings are loaded from matching environment variables. And when you're working locally, they can go on N files as well. And then after that we can access our settings as yet another component anywhere in our app. So this means we can inject it and then confidently refer to our settings using their own methods. Now aside from settings, so far we've only seen components loaded from the classes that we put in our app directory. But what about some components that might need special handling as part of their setup?

Well, this is where providers help. And we need to make one now for our email service. We've already created the setting for its API key. Now we need to use it. Providers have their own folder in config. And here we're going to register one for our email service. In the provider, we can work across a range of life cycle steps. So here the first thing we'll do is require the gem for our third party email service. And then we'll grab the API key for this service from [snorts] the settings component that we just set up. Pass that API key in to configure a new instance of our email client. And then we'll register that instance as a component in our app under the email service key. So what this means is that any class using email service as a dependency will now get this fully configured client we've set up here.

So, by this point, we've covered nearly everything we need to know about Hanami apps. But there is one last important thing for us to discover, and that's slices. Slices help us organize our app into separate domains or technical concerns, and they're a fantastic tool for introducing modularity and clearer internal boundaries to our app as it grows. Now, you don't see these in a new Hanami app, and that's because we chose to keep that first run experience as light and as simple as possible, but they are a built-in feature, and they appear as soon as we start putting any code into a slices directory.

And once again, Hanami helps us do this with its slice generator. So, let's make an admin slice. Now, this will prepare an admin slice directory for us. And that can be a place we can throw our own code like a product create action for example. Just like the app, every slice maps to a single Ruby name space. So here we're working within admin. Hanami will also give us a slice class that we can use. And this works exactly like our app offering access to components with the only difference being that it's confined to the components from its own slice directory.

And also like the app, slices come with their own depth mixin with the same restriction. It only loads components from inside the slice. So now we've seen that both the app and slices act as containers for our components. [snorts] And then thanks to our use of the depths mixin, we can also clearly recognize the relationships between those components and begin to envision our app as a kind of big directed graph. And then from here we can take things one step further because slices can import components from other slices which means we can envision an equally clear graph of all of our apps highle concerns.

This is a really powerful approach. Here we have the tools built right into the framework to help us organize our code at every level for easier understanding and maintainability. And slices also help us with our operations because we can configure exactly which slices we want to load for each specific deployment and workload of our app. So now we know everything we need to know about Hanami's features and that means we can head to the finish line. And on finishing Murakami writes, I didn't care what place I finished. I didn't care about the time. just making it to the end still running meant everything.

In these large running races, it's rarely about the other competitors. Instead, it's really about meeting your own goals. And when he wrote this, Murakami's goal was to make sure that he ran at every point across this marathon. And we can continue to run here too to head to the finish line and expand on our app one last time to get closer to a well-rounded feature. And these next steps are the same that I've taken when building production apps like this over the last 10 years. There's some really simple patterns that have held true over this whole time.

So let's get back in the code and start again with actions since they're the outermost layer in our app. Uh, we built a read action before and it didn't really have to do anything to get that product's index. This time, however, we'll make an update action and implement some of our own HTTP logic. Since we want every action to be as thin as possible, the first thing we do is bring in a dependency from the app. This is a theme you should start to notice. So, here we'll bring in an operation object for updating our product.

And then inside the actions handle method, we can call this operation passing in the ID and the params from the request and then go to work on its result. Now in the case of a success, we can redirect back to the products path. Our job's done. But if this operation fails, we can rerender the edit screen along with any error messages that are relevant. So even for a more involved action here, this is still small and understandable. And that's because we push as much logic as we can deeper into the app and leave the actions to focus on HTTP concerns only.

So let's go that step deeper now and take a look at this update operation. Here it is. And once again the first thing we do is bring in more depths. So here we'll bring in a validation contract as well as the product repo we created earlier. Now, this object is callable with the call method here being its only piece of public API. And then the first thing we do is validate the incoming product attributes because they've come from the internet by running them through our contract. And what we're doing here is the kind of attribute validation you typically see attached to a model in a Rails app. But here we're doing it with a standalone object. And this means we can tailor the validation to each specific use case in our app and keep it separate from the concerns of database persistence.

Now, we won't visit the contract in details here, but it's built using the dry validation gem if you'd like to learn more. This is a gem that fits well in Hanami apps, but it's independent, so you can use it in any Ruby app that you're working on. So, moving on. If the attributes coming out of the contract are valid, well, we can update the product in our database via the repo and then return that updated product as a success. Otherwise, we consider this a failure and pass those validation errors back to the caller.

Now, success and failure here are two sides of what we call a result object. And this object creates a wrapper over our specific return value, which means the caller has to consider both the success and the failure cases every time. Now, this is good for consistency, but it's also helpful for expressiveness because it's this result object that enabled the case statement with the pattern matching that we saw back in our action. And these results and this class itself is all provided as part of the dry operation gem. This is a brand new gem that we created to release alongside Hanami 2.2 last year and it provides a streamlined batteries included experience for building these service classes that we've seen here and it gives us the tools we need for our operations to remain clear and maintainable even as they grow more complex. Once again works great with Hanami but it's an independent gem so

you can drop it in whatever app you're building. So now we have one final step to take and it's to look at our last dependency. We're going to go one layer deeper and return to our product repo. And this should feel familiar. It's the same repo we made before. But here we're adding methods for creating and updating products in our database. And what we're doing here is beginning the journey of defining our very own persistence API for our products. And over time, we'll grow this for each distinct way we want to work with products from our database, like fetching an individual product by its ID or a pageionated collection of products within a category. And these repos can scale all the way from the simplest to the most complex SQL all while using the same query API underneath. And what this means is that these repos can serve as a single unified access layer to our persistent data.

And because we're building these repos ourselves, we bring intentionality to this access because we're the ones creating the methods, picking the meaningful names, using the repos as dependencies where we need them. And together this means we can much more effectively manage how we work with our persistent data across our app. Now adopting this repository pattern was one of the most impactful things I encountered when I was learning a new style of app back in 2015 and beyond because it has so many positive flow and effects. And we can see this in action by looking at the objects these repos return which is our own strruct classes representing the various entities in our app, the nouns in our domain.

And the repo uses these when it finds a matching class name just like here with product. And these are value objects only. Just data, nothing else. No live connection back to the database. No way to trigger additional queries. which means we can feel confident in passing these all around our app and know that things like n plus1's from our views are resigned to the paths. And of course inside our strrus we can expand on how we interact with our data just by defining our own methods. Every attribute we select in our queries will be available for us to use just like here with description.

And our repos can return different kinds of strrus too. All we need to do is specify the strruct name in the query and a matching class will be used. So together this shows how our repos can serve as the means of decoupling our app's business layer from the details of persistence. And then as our app grows, we can further emphasize that decoupling because we don't just have to create repos that are onetoone mappings to our database tables. we can arrange them to reflect all the distinct areas of our business domain.

Now, there's only so many steps we can take in our time together today. So, if any of this is interesting to you, come find us on the internet, like in the Hanami Discord or forum, and we can chat about how things can grow from here. But by this stage, you've hopefully noticed the differences in our Hanami app compared to what you're probably familiar with of Rails. In Hanami, we prefer more focused classes. This means a greater number of classes and a clearer responsibility for each. And then the framework gives you the tools to help bring those focused classes together to realize your highle features.

And each of these components in a Hanami app is also immutable. This takes away the dimension of time from your code, making each piece way easier to understand, test, and combine. And then we want to help you have that focus at the whole of app scale, too. So, Hanami encourages you to build your app in distinct layers rather than blending everything together. With Hanami apps, at minimum, you'll have a HTTP layer, a business layer, and a persistence layer. And then with slices, you can create as many other layers vertically or horizontally as you need uh for your app to express its domain.

And all of this allows you to work with greater confidence in each layer with a focus on its needs alone. And then Hanami is also firmly of the opinion that the framework should not be your app. It should not consume your app. These are separate things. We think the framework should be a tool that works in service of your app, not the other way around. Panami routes and actions, for example, are intended to be the thinnest possible gateways into the core of your app. And from there, that core business logic is yours. It's supposed to be separate from the framework level facilities.

And this lets you construct your app in whatever way that makes sense for your domain. This is where you get to do actual software design. And it's within that space where I made my leaps as a developer. Now, all of these these Hanami ways, uh, they're trade-offs and they're not going to be for everyone. And even if you know, some of you might say they're not for you. I bet there's a bunch of people sitting there quietly nodding your head and going, "Yep, I wish I had these to help me when I was making my apps." And what I'm proud of is how accessible we've made this style of app today. the when I started on my personal journey of Ruby discovery, well, it was really a wilderness out there. To make something like this, I had to search far and wide and start cobbling things together from scratch and even invent some pieces that were missing. But today, we've turned it into a single gem install. You can jump

straight in and start playing and learning. And that brings us to our next chapter. How Hanami can bring about Ruby's next evolution and why I think it's essential. Now, it might be easy to look at all this Ruby I've just shared so far today, especially with Hanami as a full stack framework and see it as an opposition to Rails, but just like the race we've just run, I don't see this in terms of competition. I don't see Hanami and Rails as a black and white either or thing. I see it more as a yes and thing. So many of our gems can slot right into Ruby on Rails apps. They can help you level up in the areas you need it most.

Pull in dry operation and experiment with results as a way to combine your service object. Use dry validation to play with some advanced validation in the endpoints that need it the most. Or create your own strictly typed immutable value objects with dry types and dryuct. We've even had someone in our community experiment with mounting entire Hanami slices into Rails apps and it works. But we're here for more than just Rails though. We want to elevate all of Ruby. And just like Murakami felt a kinship with his fellow runners on the course, we feel the same about our fellow Rubists. These are our people and we want to lift them up. We want our tools to work together with Ruby apps and Ruby gems of all kinds.

So this is why Hanami is okonomi. That's the Japanese for as you like it. The choice is yours. This philosophy is at the core of everything we do. And while we do provide a cohesive batteries included framework experience as a starting point, there are two more things that are true about it. It's built on top of all of these gems that are independently useful. So you can use them as standalone pieces as you like it in any kind of app. And Hanami itself is designed to let you remove its pieces and replace them with other things. So once again, your app can be exactly as you like it. And we want more of this. So I want to share really briefly some examples of the Okonomi Ruby that we want to foster.

Let's take a look at a few of my favorite Ruby gems. And the first is ROA, a routing tree web toolkit from California native Jeremy Evans. ROA lets you define your routes as a series of nested Ruby blocks and with your own logic sprinkled along the way. And if that's how you like to do your routes, well, you can swap rotor in for Hanami's routing layer. It just works. Next, we have Flex by Joel Drapper. Flex lets you define your views entirely in Ruby again by a series of nested blocks. And if you like that idea, well, you can use Flex instead of Hanami's views.

And yes, maybe this is not so radical. Ruby works with Ruby. What's the big deal? But what I haven't featured in that short list are the thousands of Ruby gems that exist as Rails plugins alone. Rubists using other frameworks can't access their functionality. And I want Hanami to help change the picture here. And we're lucky to have some good examples to follow. The first is Road again from Jeremy Evans. Jeremy calls Rodoth Ruby's most advanced authentication framework. And like Jere everything Jeremy says, I'm inclined to believe him. And what's special about Rodoth is that it's built on top of Roa, which makes it really lightweight, really flexible, but also really pluggable. And so you can use Rodoroth to to natively authenticate Hanami actions. And I have a blog post about this if you'd like to see how.

And next we have Shrine by Yanko Marinich. And this is a Ruby gem for handling file uploads. Now Rails developers here are possibly working with older gems like carrywave or paperclipip or active storage in more modern days. But what I like about Shrine is that while it does support Rails, it's also framework agnostic. Shrine ships with support for many persistence libraries and frameworks thanks to its adapter oriented architecture. So thanks to Shrine, if I want to build with a non-Rails framework, I still have access to best-in-class file upload support. This is a big deal. Yanko didn't have to build Shrine like this.

He could have written it for Rails and found himself a good many users, but instead he made the righteous choice to enhance the entire Ruby ecosystem. And I love this because I love Ruby and that's why I love things like shrine rod flex and rotor. I think gems like these and the people behind them represent the best of Ruby because they push boundaries. They explore novel approaches. They let us see and use Ruby in new ways and they do it in a way that lifts up Ruby apps of all kinds. Rotor was in fact my own gateway to this new style of Ruby. It was the first tool I picked up on my path towards Hanami.

So, Hanami is not the only example of Okonami Ruby out there. There are at least a few other folks, maybe black sheep like me, who care about the same things. And that is what I love to see. But as much as I love Ruby, I also worry about Ruby because Ruby is like our knees. Uh, at one point in Murakami's memoir, things take a startling turn when all of a sudden his right knee buckled while walking down some stairs. He couldn't put any kind of weight on it. And for someone who lives to run, this was a grave development. It made Murakami pause and give serious thought to his knees for the first time. And as he wrote, "You can replace your breath any number of times, but not your knees.

These are the only knees I'll ever have, so I'd better take good care of them. Now, when I worry about Ruby knee health, what comes to mind is Ruby's diversity, or lack thereof. Now, when I've done this talk before, I'd normally ask for a show of hands, but it's going to be awkward with me not seeing you. So, what I'm going to presume here is that a lot of the folks uh listening who are paid to work with Ruby, well, for nearly every one of them is going to be doing it with Ruby on Rails because that's our reality right now. We're a pretty lopsided community. And we could call it a monoculture. And hey, maybe it's not a problem. Here we are, you know, at a beautiful Exo Ruby today, the the one of many. Uh but monocultures do pose risks due to monoculture. We completely lost the world's default banana to root disease in the 1950s.

And then closer to home when Internet Explorer completely dominated the web, we lost a decade of progress and innovation. And how did IE get to this position? Well, at the beginning by being a good and free technology choice. Well, we have a good and free technology choice in Ruby too. Ruby on Rails. But when we lack diversity around it, we're missing out on something and we just can't see what it might be. So, say I came to the Ruby community today with fresh eyes and surveyed what I saw. Well, what I'd see is, well, a little too much gravity behind a Ruby orthodoxy. That's no moon. Now, Ruby on Rails is popular as it is for good reason. But if you zoom out, it's kind of the only show in town, and it does continue to evolve, but it's also mature. So, its direction and its people are already set, and there are certain parts that feel immovable at this point, and that has a chilling effect on a

certain kind of Ruby creativity. And then if I continued to survey Ruby with my fresh eyes, what I'd also see is a higher level leader who or two whose personal values are at odds with most of the community, certainly at odds with mine. And I think that's very relevant today of all days. And if that was the whole story, well, and I was coming to Ruby today, well, maybe I would bounce right back off and maybe I would go use elixir. But it's not the whole story. And I'm not coming to Ruby today. I'm already here. So instead, I've been building a quiet little rebellion against the orthodoxy. You've just seen it. I'm creating I'm working to create a world where frameworks like Hanami are no longer considered outside the mainstream. I want to expand the mainstream to create another center of gravity within Ruby and one that encourages more pluralism in our community where we have gems like Road

and Shrine becoming commonplace and together we lift up Ruby people and Ruby styles of apps of all kinds. This will help lower the barrier to even more joyous experimentation in Ruby. It will help more people find their true homes in the community. And right now in this rebellion, I am forming an alliance. And with that alliance is how we can be better seen and heard and better build our vision of a more diverse Ruby. So when we built our Hanami app earlier, we did so with the support of numerous dry libraries and a database layer powered by ROM. And it's in these three projects that we have our alliance. They fit together exceedingly well and they offer outstanding breadth from focus libraries to a persistence toolkit all the way to a full framework. And for a while now it's been the same team maintaining all three of these projects.

So this year we've been working to bring them together. We're rebooting our projects and revitalizing them for the future. Hanami Dry and ROM are here to stay, but from now on they'll be part of a new family. We're calling it Haneka. This is our gathering of Hanami Dry and ROM and you are some of the first people to be hearing about this. Uh we're we're aiming to get a a launch out this year, but I'm very happy to be sharing it with you today and I'd love to hear from you later about what you think of this direction.

Now, in the Hanekai name, we're continuing with the spirit of nature and community from Hanami. In Japanese, the hanekai loosely translates into a party of flowers. And with Hanekai, we're bringing our blossoms together. Hanami dry and rom. And we invite you to join us, too, because we want to help your Ruby bloom. With Hanekai, you can elevate your apps from drop-in gems to the full framework experience we saw today. With Hanekai, you can elevate your skills by experiencing a different style of Ruby. A blending of functional and object-oriented styles with clear separations of concern and clear data flows. With Hankai, we want to help elevate the Ruby community at large by creating this new center of gravity that encourages people to look at Ruby in a new light.

So, this is the start of a new era for us, and I'm very excited for it. But there's still a lot to do to make it happen. We've been working towards some clear goals uh on this path. The first is establishing this new community and so far we've unified our community spaces. We're building a fantastic new website too to bring our docs and resources all together. And as part of this, we're trying to make it clearer for new contributors to participate in our projects. So if you're someone who knows Ruby and wants to contribute to open source, there's tons of opportunity here. And along all of this, we're being very intentional with this evolution of our community. We're leading with our values.

More than anything, we want Hanekai to be a welcoming place for those who bring kindness, curiosity, and care. A place where people of all backgrounds and experience levels can feel respected and can share and grow. A place a place we want people to feel proud of and feel safe within. And this also means being clear on what we won't tolerate. So this is why we also place these words right up front on our website and in all our community spaces. We will not tolerate Nazis, transphobes, racists, bigotry of any kind. Again, really timely for today. We are here for people before technology as the most important thing.

Now to understand our second goal, we need to go visit another time in Murakami's life. one that even predates his life as a runner. Before Before Murakami became a novelist, he spent seven years running a jazz bar in Tokyo. He and his wife hated the idea of having to fit into the system of orthodoxy. So in 1974, they took their own path and opened up this bar even before they are done with university. They had records playing constantly and young musicians performing live jazz on the weekends. Sounds like a wonderful space, but it was hard work for them. And it was while he owned this bar that Murakami decided to write his first novel. He would spend one to two hours in his kitchen writing every night after closing the bar. He had to do this in spurts, snatching bits of time here and there, competing against the clock as he wrote.

And when he recalled this time, Murakami said, "I felt like I was living enough for two people's lives." Then he did it all over again for his second novel. And finally after that he decided to shut the bar down. This was not the environment for him to produce the complex profound novels he would come to be known for. Now running this bar and writing on the side is where I and where the Hanukkah team have been for the last decade. Nights and weekends the whole time. And like Murakami, I know I need a change to make things more sustainable, to create the environment, to build even better things. So that's why our second main goal was to fund raise for sustainable maintenance of Hanukkah. We spent 10 years building this comprehensive ecosystem. Now we need your help to take it to the next level. We are looking for you and your businesses to become Hanekai patrons.

And our goal is to start paying the people who build Hanami, Dry, and ROM, all of these things. We're starting with just one day a week from me. Uh I've already uh been in that pattern for a few months. And if we can raise more, we'll do the same from Shan Collins, my teammate now. This is a modest first target, but it is having a big impact on our projects and on our people. And we think sustaining this is achievable. We we are off to a good start. We've already raised $27,000 thanks to these amazing founding patrons. So, thank you to Sidekick, Honeybadger, Fast Ruby, App Signal, and Ruby's very own Brandon Weaver. And we really love to see you and your businesses. Join them as founding patrons. You can help us make a better Ruby. We're doing this because we love Ruby. After all, we have just one Ruby.

Ruby is our knees. We need to take care of it. Now, let's bring it home. On the surface, Murakami's memoir is about his life as a runner and its connection to his life as a novelist. But at a deeper level, though, this is a qu quiet but powerful meditation on his acceptance of his individuality and his embrace of his individual purpose. On the topic of his writing, Murakami writes, "I never had ambitions to be a great writer. I just wanted to write something that was mine and that no one else could write. And likewise, I didn't start running because someone asked me to become a runner, just like I didn't become a novelist because someone asked me to.

One day, out of the blue, I wanted to write a novel. And one day, out of the blue, I started to run simply because I wanted to. I've always done whatever I felt like doing in life. So what do I talk about when I talk about Ruby? Well, I want a Ruby where we reduce the barriers to people simply doing what they want to do to being their true selves writing the things only they could write. With the Ruby language, we're already bre blessed with something that supports all kinds of expression. What I want for us now is to match that with the community and the ecosystem we build around it.

This means a more diverse Ruby. both socially and technically. And through that diversity, we can nourish our community. A more diverse Ruby keeps more of us here because the people can find the tools and the groups that suit the way they want to work uh the gem servers they want to use. A more diverse Ruby can also attract people and help grow our community, which is essential because we can offer a wider range of options if we're more diverse and meet more people where they are on their own journeys. We can make homes for all the black sheep. But not just the black sheep, the sheep of all colors.

Now on my personal journey, it was those 10 years ago in 2015 that I discovered my place, my purpose within Ruby's diversity. And this is that is when I finally discovered the Ruby that suited me as a person. The Ruby that I wanted to do for the long run. And then once Murakami found writing, he took up his long runs so he could live and write for longer. Then for me and Ruby, once I started building Hanekai, I did this because I wanted to write and see more of that Ruby in the world. Just like running marathons, this is work that requires persistence. And I know and at some points truly feel that too. But I think Murakami puts it well.

Pain is inevitable, but suffering is optional. Hard things become easier when you feel that connection to purpose. I've now been doing this for 10 years, and with some help, I'm ready to do it as long as I can. And Murakami is a worthy role model here, not just for me, but for all of us, because he is still running every day, well into his 70s, and he's made it past 40 marathons. Now I haven't run a marathon myself and maybe after doing this talk a few more times I'll be inspired to do it. But even without that experience I completely understand Murakami when he describes a good run as being contagious.

In my case it was only after striking out on a new direction that I truly started learning and getting the most from my work with Ruby. Everything started falling into place from there. Ruby changed me and in turn in my way I change Ruby too. And what we see in Hanekai is the result of that today. And my hope is that we can help others forge their own directions too and create a more interesting, more diverse Ruby for all of us. So that's been my journey with Ruby, a a little version of my own memoir, the path that I followed and and where I want to go from here. And as this conference wraps up today and we all go our separate ways, well, I'd love for you to take a moment and ask yourself, what is the path that you want to take in Ruby? What is it that only you can do?

And if you think of something, I'd love to hear from you. So send me an email. And if the path you want to take overlaps with ours in Hanami or Hanekai, please check it out. Whether you want to try it, contribute to it, or even provide financial support, we'd love to hear from you. Uh, and yeah, that's it from me. So, Jim and Exor Ruby organizers, thanks for finding a way for me to beam in today. And to all of you, uh, thank you for hearing what I talk about when I talk about Ruby. Yeah, I can see it. So, Sam asks, "If every action is his own class, how does Hanami nudge developers away from using mixins to share common behavior?" See, the thing I like about Hanami's design is it's just object-oriented Ruby. So the choice is yours. And I think the the the tendency to go towards mixins is when you don't have a a tool kit that helps you with composition. So Hanami's depths mixin is all about composition,

bringing different objects together where each object uh fulfills a certain purpose and that is the thing we try and make easy. And by putting the depths mix in at the very top of your class, it means you start to have a conversation with your code. uh you know if you go to a class where you see a few depths where you know what uh behaviors it's leveraging from the app and then if that list starts to get a bit long you might think well hey maybe there's an abstraction that's missing that can bring some of these together into more a more cohesive interface but at the same time there are cases where mixins make a lot of sense and you still have that uh tool available to you because we're just building plain old Ruby and that means as the author you get to pick whatever technique makes the most sense for your needs. Uh yeah, thanks Sam for the question.

Yeah, thanks everybody. See you on the internet.

Questions about this episode

What is discussed in "XO Ruby San Diego 2025 - What I Talk About When I Talk About Ruby by Tim Riley"?

In order: 0:00 Haruki Murakami, Exor Ruby, Hanami, Sputnik Sweetheart; 5:00 Hanami, Elixir, Haruki Murakami; 10:00 Hanami, Haruki Murakami; 15:00 Hanami, Haruki Murakami; 20:00 Hanami; 25:00 Hanami, Haruki Murakami; 30:00 Hanami, Shrine, Haruki Murakami, Rodoth; 35:00 Hanami, Hanekai, Hanekai, Elixir; 40:00 Haruki Murakami, Hanekai, Hanekai, App Signal; 45:00 Hanekai, Hanekai, Haruki Murakami, Hanami.

What is mentioned in this Confreaks episode?

20 people, works and ideas are mentioned, including Hanami, Haruki Murakami, Ruby, Hanekai, Hanekai, Shrine. Each one on this page links to its own page with every episode that mentions it.

How long is "XO Ruby San Diego 2025 - What I Talk About When I Talk About Ruby by Tim Riley"?

The episode runs 50 min; the transcript is about 8,544 words in 66 timestamped sections.

More from Confreaks

About this transcript: the episode's spoken words as captioned on YouTube, split into timestamped sections. Reclip.Me locates every person, work and idea in the text, keeps the time it is first named, and quotes the words around it verbatim. Last updated January 24, 2026.