
Principal Whimsy Engineer for myself, Staff Software Engineer for @GustoHQ. Hobby hobbyist, husband, father, noun, https://teapawt.net/t.co/9L8pwSaRrY . Opinions are my own.
Atlanta, GA
Joined June 2007
- Tweets12.6K
- Following2.7K
- Followers2.9K
- Likes12.3K
Josh Nichols retweeted
Most companies didn't go remote — they digitized the office. Same meetings, same interruptions, now on Zoom.
Open and Async is out today: the open-source way of working — in the open, in writing, async by default — turned into a playbook for your team.
open-and-async.com
PSA: if you need the exact text off a page in Claude Code, don't WebFetch it. curl it.
WebFetch laundres the page through a small summarizer model. You get a paraphrase, not the bytes. Fine for the gist, wrong for exact docs/API signatures/llms.txt.
bit.ly/3R3DPN0
Josh Nichols retweeted
Situation 1: dev A thinks approach X is correct, dev B thinks Y is the right way. They argue and try to convince each other.
Situation 2: dev A thinks approach X is correct, tells the LLM to implement it.
There is SO MUCH learning in Situation 1, lost when using LLMs....
Claude Code prompts for `python3 -c '# comment\nprint(42)'` even with auto-mode on. Not a bug.
There's a Bash parser in there with opinions, one of 6 layers between your keystroke and execution. Mapped them all.
pickles.dev/claude-codes-per…
Repeat after me: CLAUDE.md, skills, and anything else in the context window is at best a suggestion. Hooks are the only way to enforce behavior
two weeks running Claude Code with /sandbox. here's the config that actually works, the stuff that broke, and the stuff that's still broken.
pickles.dev/the-sandbox-conf…
"That's awesome, congrats" takes thirty seconds. "Great, now what about Y?" takes the same thirty seconds but leaves someone deflated.
Wrote about the skipped acknowledgment and why we keep doing it to each other
pickles.dev/can-we-just-sit-…
~/.claude/ is basically production. No staging, no isolation. Every Claude Code plugin mutates your daily driver config. Wrote up how to set up a proper test environment after borking mine one too many times. bit.ly/4r7VlvC
My team is hiring! Come work on sidekiq, karafka, and other async stuff with Gusto (see what I did there?)
job-boards.greenhouse.io/gus…
Josh Nichols retweeted
Stumbled across notes from my first @RenderATL (always keep your notes!). From @kishau :
"Don't create glass ceilings for yourself by being an ineffective communicator and not being a good storyteller... If you make a technology choice, be able to talk through the alternatives you didn't pick and why"
still true and relevant for my current role I didn't even have then🙏🏾
Josh Nichols retweeted
"None of our top 50 endpoints by throughput can have more than 5% of responses be >500ms"
This is a good perf goal. It scopes to the most important parts of the app, is set based on expectations of human users (users can feel >500ms resp), and it's usually quite achievable.
Josh Nichols retweeted
I just released Zeitwerk 2.7.
Now, you can define namespaces with manual constant assignments too (think, Namespace = Struct.new).
To the best of my knowledge, this completes the most important goal of the gem: to fully match Ruby. 🎉
Let me elaborate a bit on why that was not supported before, and how we have been able to remove that long-standing limitation.
First, let's take a step back to understand a tricky aspect of namespaces. Consider this Hotel namespace (in Ruby, both classes and modules can be namespaces):
# hotel.rb
class Hotel
include Pricing
end
# hotel/pricing.rb
module Hotel::Pricing
# Pricing related logic extracted to a mixin.
end
You cannot load any of the two files in regular Ruby, right? To load hotel.rb you need Hotel::Pricing in place, but if you try to load hotel/pricing.rb, you need Hotel!
But that works if the project is managed by Zeitwerk, and it worked with the classic autoloader too.
To support that use case, the :class event of TracePoint was instrumental, and it was the only technique I could think of in 2018.
It worked this way: When TracePoint notifies that Hotel has been created, the loader scans its subdirectories and defines autoloads (issues Module#autoload calls) for child constants, in particular for Hotel::Pricing.
The key observation is that happens precisely before the include line is executed. When the interpreter hits that line, the autoload is in place and autoloading hotel/pricing.rb is possible (because Hotel exists!).
Problem was, the event was not triggered for manual constant assignments (think Hotel = Class.new). So, while that was a corner case, unfortunately we could not achieve full parity with this technique.
The most important and common way to the define namespaces, using the class/module keywords, worked. But argghhhh.
But the suffering is over my friends!
In part motivated by this problem, @_byroot implemented Module#const_added. That callback is invoked in both situations! 🤘
Thanks to Module#const_added, the limitation has been finally removed. Also, Zeitwerk no longer uses TracePoint internally (/cc @yukihiro_matz).
Zeitwerk 2.7 requires Ruby 3.2 or later, and upgrading should be seamless for existing projects.
Don't worry if your app uses an older Ruby. Bundler realizes 2.7's Ruby version constraint is not satisfied, and ignores it in that case. Gemfile.lock will always get a version compatible with your app.
Same for gems that need to support Ruby versions older than 3.2, a version constraint for zeitwerk like ~> 2.6 will do the job. Client code will automatically use a compatible one.
Mission complete! 🎉
Josh Nichols retweeted
We're hiring engineer #4 at @scholarlysoft on-site in Seattle.
If that's you, let's chat! DMs are open.
scholarly.breezy.hr/p/a8959b…
Very exited and proud to be sponsoring #railsconf this year. I’ll be at the open source hackday working on singed, a performance debugging tool!
medium.com/gusto-engineering…
Josh Nichols retweeted
I have a long list of ideas I want to work on but not enough time. I do have some money though. Is it time for Speedshop's first employee?
If you are:
1. A good writer
2. A solid Rubyist that can build a product from start to finish
... maybe it's you?
Josh Nichols retweeted
Our system tests were slow and we couldn't figure out why... turned out it was a 1-line fix!
I've written this post for @GustoHQ's engineering blog: engineering.gusto.com/our-ru…
Josh Nichols retweeted
Gusto's @techpickles has shipped Singed, a swiss-army-knife tool for getting flamegraphs anywhere in a Ruby application: github.com/rubyatscale/singe…
It slices, it dices, it profiles:
* Blocks
* Tests
* Requests
* Controllers
* Command line
... all using Speedscope! It's great.










