2025 In Review
Table of Contents
I knew this year would be busy, I just didn’t know how much so. Being a dad changed my life drastically, but a lot of other things happened too!
Parenting
I had so many “firsts” this year as a dad. I saw my daughter talk, eat solid food, crawl, walk, and many other things I can’t even count. It is as rewarding as it is challenging. Nothing I’ve done this year would be possible without the support of my wife, who is an amazing mom and partner. I love you two!
Career
Four years at thoughtbot. It’s been such a journey! I’m glad I have such a great place to work which allows me to grow in many different directions.
Public Speaking
I spoke in two different conferences this year: Tropical on Rails and RailsConf. Both were the same talk — Ruby Internals: A Guide For Rails Developers — but these were great achievements for me:
- At Tropical, there were over 600 people, and, not only because of the huge audience, being around great speakers like Xavier Noria, Chris Oliver, Rosa Gutiérrez, Jackson Pires and many others was inspiring.
- I had the pleasure of speaking at the last RailsConf. It was amazing to be part of a conference that I myself had watched online for years.
Going to RailsConf was my first time in the US. I had very little time there, but I did eat a cheesesteak in Philly, so it counts!
I also was accepted to Baltic Ruby and RubyConf Austria, but had to turn them down for personal reasons.
Books
I haven’t read a lot in the past years (aside from some Asimov), but I decided to read something in 2025. I read two books:
- Scar Tissue, a biography of Anthony Kiedis, the lead singer of Red Hot Chili Peppers, one of my favorite bands.
- Getting Real, from Basecamp. This is the kind of book one can revisit from time to time to get bite-sized advice on how to build a software product.
Technically, I also finished Crafting Interpreters, but I read it in parts over the years, so I’m not counting it here.
Ruby DF
Ruby DF, the meetup I run in my city, had a great year! We hosted 7 events (all time high!) with 9 talks and over 75 attendees. We also got sponsorship from Ruby Central, which allowed us to record the meetups and share them on our YouTube channel.
Blogging
I wrote 5 articles in 2025. That is half of what I wrote in 2024, and the lowest number since 2020. Of course, I had a lot on my plate this year, but I think I made up for it with the talks.
The articles were fairly distributed throughout the year, with the 3rd quarter being the most active with two articles. One of them was a guest post for App Signal about Ruby Parsing with Prism, but it was only published in 2026.
Memopack
Late 2024 I started working on Memopack, an app I’m writing for myself to replace a bunch of Google Keep notes and other stuff I had scattered around. I wanted to have a single place to keep a journal (with mood tracking), all my notes, todos, and other things like bookmarks.
2025 was when things really took off. I’ve been using it daily, and improving it as I go. Ruby on Rails is really good for taking these ideas and making them reality quickly.
I’m even using it to help me write this article. I have tags (called stickers) for my journal entries, so I can quickly find all the “first time” things I did this year, for example.
Open-Source
My gems were downloaded 87,940 times in total. That’s a ~69% YoY increase. I’ve released a number of new gems, but the most important are:
- rails-diff: a gem to help you compare files generated by Rails (like Dockerfile, .gitignore, etc) with the ones in your repository, making it easier to keep track of changes and updates. This gem started entirely vibe-coded with Windsurf as an experiment. The code got messy pretty quickly, so I had to steer the AI to write tests and do some refactoring. It’s still not great, but it got better.
- data_customs: a simple gem to help you perform safe data migrations in your Rails app. It was an extraction of some code I wrote for a client project. It has been working really well for us and I plan to keep improving it.
Smaller gems like argument_parser and planck were extractions from the bigger ones. Existing gems like
end_of_life got revamps, updates and new releases.
Rails
I made 7 commits to Rails this year, contributing to the new Sign up and Settings and Wishlists guides.
I opened a few other PRs, but the only one that got merged was adding the
helper relative_time_in_words to
ActionView. This was an extraction
from Memopack. I hope to extract even more!
Ruby
This was a great year for my Ruby contributions! I proposed a few features to Ruby core:
-
String#ensure_suffix: Approved by Matz! 🎉 This method ensures a string ends with a given suffix without duplicating it. It got discussed at the June dev meeting and Matz gave the green light. Still waiting for the merge, but I’m thrilled. -
Time#am?andTime#pm?: Rejected. The edge cases around noon and midnight (is 12:00 AM or PM?) proved too ambiguous. I proposed alternatives like returningfalsefor those times or addingnoon?/midnight?methods, but no consensus was reached. -
Array#values: Rejected. I wanted uniform Array/Hash treatment. Unfortunately, it didn’t go far. -
Enumerable#join_map: Rejected. I proposed combiningmapandjoininto a single-pass method (likefilter_mapdoes forfilter + compact). Matz rejected it, hoping JIT inlining will optimize.map { }.joinin the future instead.
Not only did I propose these, but I actually provided patches for them (some written in C). That was on my to-do list for a while, and now it’s done. I’m really proud of that, even if none have been merged yet.
I also participated in several discussions:
- Proposed
Ruby::Contextas the name for the new namespace feature (it ended up being calledRuby::Box). - Proposed
?=as an uninitialized assignment operator for memoization (although this syntax already exists in Ruby for other uses) - Suggested
zip_mapas a name forArray#zip_with.
On the code side, I fixed a bug on
RubyGems improving error handling
for missing version files. This work came from my gem end_of_life. I opened a small
PR to fix docs in Ruby as well.
Crystal
I cross-pollinated my Ruby work to Crystal! Both String#ensure_prefix and
String#ensure_suffix got
approved and merged there. I’m now officially a Crystal
contributor!
🎉
Misc
I also had small contributions to several other projects, including Kamal, Trix, Devise Invitable, Litestream Ruby, Fizzy, StoreModel, and Try.
Game Development
I didn’t work on actual game projects like Frenzy Jumpers or play with DragonRuby this year, but I gave a talk about game development for beginners.
Because of the talk, I did touch rich_engine, my little engine for terminal games, a bit.
Language Development
Last year I didn’t touch langdev at all, but surprisingly, this year I spent over 128h working on my own programming language, Lit (the inspiration for my talk Ruby Internals: A Guide For Rails Developers).
I started this language back in 2020 while reading Crafting Interpreters, but I finally finished the book and made something real out of it. I wrote the interpreter in Crystal (which is why I ended up contributing to Crystal too).
I released 3 versions in 2025:
- v0.1.0: The “Hello World” release — basically Lox with different
syntax, arrays, string interpolation, a pipeline operator (
|>), and no inheritance. - v0.2.0: Removed required semicolons, added methods on primitives,
anonymous functions, operator overloading, maps, and
else if. - v0.3.0: Made everything an expression (
if,while, blocks), added array/map literals,doblocks for one-liners, theitdefault parameter (inspired by Kotlin and Ruby), file imports, and augmented assignment operators.
let greeting = if "world" == "world" do "Hello, world!" else do "Goodbye"
# Array and map literals with string interpolation
let numbers = [1, 2, 3, 4, 5]
let scores = {alice: 95, bob: 87, charlie: 92}
# Using the `it` default parameter with do blocks
numbers.each(fn do println("Number: {it}"))
# Pipeline operator for function composition
fn double do it * 2
fn square do it * it
fn just do it # sorry, I had to
let result = 5 |> just() |> double() |> square()
println(result) # => 100
Lit is now expression-oriented and is starting to feel like a real language. My current goal is building a Lit interpreter in Lit itself, a fun challenge that helps me find pain points in the design.
Code Statistics
According to WakaTime, I logged almost 999 hours of coding this year, averaging about 3 hours and 13 minutes a day. That’s a significant jump (+41%) from last year’s 704 hours (roughly 2 hours and 45 minutes/day). GitHub confirms this, showing that I made 4006 commits, nearly 60% more than last year and an all-time high for me.
Aside from work, most of this time went into personal projects: 265 hours on
Memopack, 128 hours on Lit, and about 50 hours on maintaining end_of_life.
These aren’t numbers I’m trying to optimize for, but it’s interesting to see how they evolve over time. I didn’t expect to code more in the year I have a newborn to take care of.
Life & Hobbies
Italian
Another year of Duolingo Italian! I spent 793 minutes learning (55% more than last year), practiced on 339 days (93% of the year), and kept my streak alive for 1119 days total. That’s over 3 years without breaking the chain.
I’m mostly doing this not to forget what I already know, but it’s not a hard focus for me.
Music
Concerts
I saw Linkin Park live and it was the best concert I’ve ever been to. The setlist was perfect, the production incredible, and the crowd sang every word.
On the other side of the stage, I played 3 concerts during the year. The highlight was my graduation concert at Music School. Three years of study culminating in one night! We played a mix of international influences (RHCP, John Mayer, Fearless Flyers) and Brazilian classics (Djavan, Hermeto Pascoal, Luís Bonfá).
Streaming
I streamed 12800 minutes, 18% more than last year. I wasn’t anticipating that.
Luckily Spotify didn’t count all the kids songs I played during this year, so I got an accurate picture of my listening habits.
RHCP was the top artist and Cor dos Olhos was the top album. It’s a self-titled debut from a new indie band, and I had it on repeat.
Gear
Like I said last year, I just needed a dual switch for my Ampero, and that’s literally the one thing I got. I’m done with gear, I’m in creation mode now.
Working Out
I tried to get back to the gym after my baby was born. I wasn’t shooting for anything specific, but I wanted to get back to the routine. I went sort of consistently for January, but quit mid February. Having a baby + preparing for talks was a lot for me to handle on top of everything I already had on my plate.
Gaming
Contrary to last year, I played a lot fewer games. Yes, parenting hit me hard, but I was also focused on so many other things. Unfortunately, I didn’t see my Playstation Wrapped while it was available, so I don’t have exact numbers, but I have a good estimate. It’s a shame Playstation doesn’t have a way to retrieve my game data after the fact (no API, no official app to list it). I only played Overcooked with my wife, and by the end of the year I started Hollow Knight: Silksong.
I did get a Nintendo Switch 2 as a gift (thank you, Joice!), which opened a whole new world of games for me. Among a few minor things, I dove deep into Zelda: Breath of the Wild — amazing game BTW — Mario 3D World and some Mario Kart World. The Switch is great for playing with friends and family. The portability is a game-changer! No more boring lines or wait times anywhere!
Expectations x Reality
Let’s see how I did with my 2025 goals:
Figure out being a dad. That’s my #1 priority.
There’s no such thing as “figuring out being a dad”. I’ll always be figuring it out. I’m doing my best every day, and that’s what I’ll do for the rest of my life.
Find a new routine that works for me and my family.
Sort of. It’s really f-ing hard. I didn’t find the balance yet. I can’t work 8h a day on a chair and not exercise!
Balance work and personal life.
This has never been a problem for me, luckily. Yes, it’s hard to work and be a parent, but I have the flexibility to do it, and I have a supportive partner.
Keep my hobbies alive during this new phase.
Yes. I finished my course at Music School, did a bunch of coding on personal projects, and even found time to play some games and concerts.
Keep contributing to Rails and Ruby.
Heck yeah! I think my contributions are getting more tangible. Not only feature requests, but actual code proposals and bug fixes.
Keep the Ruby DF meetup going (at least 4 events).
Yup! Not only 4, but 7 events! We had a great year, and I’m really proud of what we built.
Propose more features to Ruby (and hopefully get one accepted).
I guess I did just that. Four proposals, one accepted. Not bad!
Talk at more events.
I did it! And I’d speak even more, if I had the time.
Keep writing (aim at 10 articles).
I wrote, but not 10 articles. But I made up for that with the talks!
Be more consistent at working out (aim at 2 times a week).
😓 Not at all…
Writing This Article
This was the article that took me the longest to publish. Not because it took longer to write, but because I couldn’t find the time to start it. This was actually the fastest one to write because I could use AI to do manual work like going through all my activity on the Ruby Redmine, instead of me going week by week to collect the data.
That made my writing speed increase by approximately 35% compared to last year (from 371 to 500 words/hour).
2026 Goals
This was an amazing year. I got to give talks, visit a new country, see my daughter learn so many things, and contribute to the community many different ways. I wanna keep all of that going, and more! Here are my goals for 2026:
- Keep giving talks. Keep writing.
- There’s not a set number for either of these (as long it’s more than zero), but these are habits I want to keep.
- Keep Ruby DF going strong.
- Keep contributing to Ruby and Rails.
- Keep extracting stuff from real projects as patches and gems.
- Open-source Memopack?
- I think it could help others too. I’m not sure what’s the best path to make this a business.
- Play in at least two concerts.
- Music is a big part of me, and I want to keep it alive.
- Get back to the gym. One, two times a week. Anything!
- I just can’t afford not to do it.
Can’t wait for the next year and all the surprises it has for me! Until then.