justin․searls․co

A simple calculation

Whenever I need to verify a network connection with a remote LLM, I always ask it 1+1. I'm sure it'll still raise the ocean level by a millimeter, but it seems less bad than a more complex query.

I forgot I had unhidden chain-of-thought reasoning, so I chuckled when I got this:

Sure thing! The task is straightforward: I just need to respond to "1+1" with "2." It's a simple calculation, so I won't overthink it. There's no need to use any tools for this, and I know the guidelines about "Destructive Deletions" and "No Comments by Default" don't really apply here. I'll just keep it short and clear, and the answer will simply be "2."

At least it didn't overthink it.

Visionaries, Entrepreneurs, and Innovators

This is a copy of the Searls of Wisdom newsletter delivered to subscribers on September 11, 2025.

Hope you're having a lovely September so far. Hard to believe it's almost Fall! Always love seeing the first signs of the end of Summer—I refer, of course, to Apple's annual iPhone event.

In case you don't subscribe to my every waking moment, some highlights of stuff I put out over the last month:

Every month, I scroll through the last month of photos for one to include in this newsletter. Not many pictures this month, so here's a little surprise Becky left me that showed up in our iCloud Shared Photo Library

How dare you assume this coaster saying that I add liquor to my protein shakes is true even though it is

I feel personally attacked. And thirsty.

Today, I'm writing you about my favorite topic: capitalism. Or, more specifically, I'm here to shed a little light on a few "special" kinds of people who tend to be highly-valued in the economy but who are often portrayed as stereotypical caricatures. Each is as stubbornly human as the rest of us. Each possess an unusual blend of attributes that make them well-suited for the current epoch. My consulting career brought me face-to-face with more than my fair share of these people. The experiences I reflected back on while writing this were sometimes interesting, sometimes impressive, and rarely both.

Content warning: more content…

Breaking Change artwork

v43.1 - iPhone 17 Event Review

Feature Release

Video of this episode is up on YouTube:

It's an emergency bonus edition of Breaking Change as I take the covers off yet another show-within-a-show. I call it Feature Release, and its job is to fill in that middle number in our semantically versioned series of conversations together. No pun, no news, just some timely content wrapped up in a name, logo, and jingle package that still has that new podcast smell.

It's a 1-hour review of the Airpods, Apple Watch, and iPhone updates Apple announced today. You can see the full event video on YouTube. The Verge has a 17 minute abridged version if you just want the synopsis.

Please enjoy this episode of Feature Release! It may be the only one. Write into podcast@searls.co with your feedback!

Mike Judge thinks developers may be deluding themselves into thinking AI coding tools are making them more productive:

My argument: If so many developers are so extraordinarily productive using these tools, where is the flood of shovelware? We should be seeing apps of all shapes and sizes, video games, new websites, mobile apps, software-as-a-service apps — we should be drowning in choice. We should be in the middle of an indie software revolution. We should be seeing 10,000 Tetris clones on Steam.

If you read the post, he's got data to this effect.

I've got two problems with this:

  1. Much of his data basically stops around March–April 2025—the precise window when AI coding tools finally became worth a damn

  2. Whether or not we're seeing a shovelware boom is orthogonal to the question of whether canny developers' output is being supercharged by AI. All it takes is one developer to show one project that was delivered in less time than they'd have been able to do otherwise and bingo-bango: AI tools as they exist today—flawed as they might be—can do something a human couldn't have done otherwise. Sure, you could make an argument about the macro-level effects—like whether the vast majority of professional programmers are too stupid or resistant to change to leverage these tools and are even somehow being slowed down by their existence, but I'd probably agree with you

Seriously, suggesting that AI-generated code is a nothingburger because we haven't yet been drowned in shovelware just four months after coding agents became remotely useful? Get outta here. And right now, only the early adopters are even using them! I talked to a manager the other day whose team has been given carte blanche to burn through all the Anthropic tokens they want and for whom not a single developer touched the account in the month of August.

I think it's important context to know that a lot of the statistics Microsoft and Anthropic put out are inflated because they have an obvious conflict of interest to push the message that the thing they sell is useful. I'm sure because many developers have GitHub Copilot turned on, they tend to press Tab without reading, then waste time mostly deleting what it produces. But, because the user mindlessly pressed Tab, somewhere a cell in a spreadsheet labeled "acceptance rate" ticks up. In practice, I suspect far fewer people are using these tools in anger than the big tech companies are incentivized to portray.

Having a full-fledged agent that can build shit for you and verify things work is—when it comes to productivity—nowhere near the same league as tacking autocomplete and an LLM chat sidebar into an editor. And here's the promised counterexample: I built some shovelware of my own last week. Took about a day of wall time to build and another calendar day for me to tighten up with feedback. I spent probably a grand total of three hours staring at computers in the furtherance of the project. This blog post about it took me twice as much time. Would have taken me weeks to build by hand, and more importantly, it wouldn't have been built at all—I wouldn't have bothered.

Thanks to exercise and clean living, my resting heart rate is 35-45. Got an EKG, all looks good.

Cardiologist: damn you're incredibly healthy

Also cardiologist: here are four follow-up appointments to blow through that pesky deductible

Copied!

Just fired up my Oculus Quest 2 for the first time in two years and—this will shock you—my $3500 Vision Pro has completely spoiled me.

How did I ever use this thing?

Copied!

There are fully six podcasts devoted to Curb Your Enthusiasm and not a single one is named Curb Appeal.

So much for that intelligent audience.

Copied!

Distributing your own scripts via Homebrew

I use Homebrew all the time. Whenever I see a new CLI that offers an npm or uv install path alongside a brew one, I choose brew every single time.

And yet, when it comes time to publish a CLI of my own, I usually just ship it as a Ruby gem or an npm package, because I had (and have!) no fucking clue how Homebrew works. I'm not enough of a neckbeard to peer behind the curtain as soon as root directories like /usr and /opt are involved, so I never bothered before today.

But it's 2025 and we can consult LLMs to conjure whatever arcane incantations we need. And because he listens to the cast, I can always fall back on texting Mike McQuaid when his docs suck.

So, because I'll never remember any of this shit (it's already fading from view as I type this), below are the steps involved in publishing your own CLI to Homebrew. The first formula I published is a simple Ruby script, but this guide should be generally applicable.

Glossary

Because Homebrew really fucking leans in to the whole "home brewing as in beer" motif when it comes to naming, it's easy to get lost in the not-particularly-apt nomenclature they chose.

Translate these in your head when you encounter them:

  • Formula → Package definition
  • Tap → Git repository of formulae
  • Cask → Manifest for installing pre-built GUIs or large binaries
  • Bottle → Pre-built binary packages that are "poured" (copied) instead of built from source
  • Cellar → Directory containing your installed formulae (e.g. /opt/homebrew/Cellar)
  • Keg → Directory housing an installed formula (e.g. Cellar/foo/1.2.3)

Overview

First thing to know is that the Homebrew team doesn't want your stupid CLI in the core repository.

Instead, the golden path for us non-famous people is to:

  1. Make your CLI, push it to GitHub, cut a tagged release
  2. Create a Homebrew tap
  3. Create a Homebrew formula
  4. Update the formula for each CLI release

After you complete the steps outlined below, users will be able to install your cool CLI in just two commands:

brew tap your_github_handle/tap
brew install your_cool_cli

Leaving the "make your CLI" step as an exercise for the reader, let's walk through the three steps required to distribute it on Homebrew. In my case, I slopped up a CLI called imsg that creates interactive web archives from an iMessage database.

Create your tap

Here's Homebrew's guide on creating a tap. Let's follow along how I set things up for myself. Just replace each example with your own username or organization.

For simplicity's sake, you probably want a single tap for all the command line tools you publish moving forward. If that's the case, then you want to name the tap homebrew-tap. The homebrew prefix is treated specially by the brew CLI and the tap suffix is conventional.

First, create the tap:

brew tap-new searlsco/homebrew-tap

This creates a scaffold in /opt/homebrew/Library/Taps/searlsco/homebrew-tap. Next, I created a matching repository in GitHub and pushed what Homebrew generated:

cd /opt/homebrew/Library/Taps/searlsco/homebrew-tap
git remote add origin git@github.com:searlsco/homebrew-tap.git
git push -u origin main

Congratulations, you're the proud owner of a tap. Now other homebrew users can run:

brew tap searlsco/tap

It doesn't contain anything useful, but they can run it. The command will clone your repository into their /opt/homebrew/Library/Taps directory.

Create your formula

Even though Homebrew depends on all manner of git operations to function and fully supports just pointing your formula at a GitHub repository, the Homebrew team recommends instead referencing versioned tarballs with checksums. Why? Something something reproducibility, yadda yadda open source supply chain. Whatever, let's just do it their way.

One nifty feature of GitHub is that they'll host a tarball archive of any tags you push at a predictable URL. That means if I run these commands in the imsg repository:

git tag v0.0.5
git push --tags

Then GitHub will host a tarball at github.com/searlsco/imsg/archive/refs/tags/v0.0.5.tar.gz.

Once we have that tarball URL, we can use brew create to generate our formula:

brew create https://github.com/searlsco/imsg/archive/refs/tags/v0.0.5.tar.gz --tap searlsco/homebrew-tap --set-name imsg --ruby

The three flags there do the following:

  • --tap points it to the custom tap we created in the previous step, and will place the formula in /opt/homebrew/Library/Taps/searlsco/homebrew-tap/Formula
  • --set-name imsg will name the formula explicitly, though brew create would have inferred this and confirmed it interactively. The name should be unique so you don't do something stupid like make a CLI named TLDR when there's already a CLI named TLDR or a CLI named standard when there's already a CLI named standard
  • --ruby is one of several template presets provided to simplify the task of customizing your formula

Congratulations! You now have a formula for your CLI. It almost certainly doesn't work and you almost certainly have no clue how to make it work, but it's yours!

This is where LLMs come in.

  1. Run brew install --verbose imsg
  2. Paste what broke into ChatGPT
  3. Update formula
  4. GOTO 1 until it works

Eventually, I wound up with a working Formula/imsg.rb file. (If you're publishing a Ruby CLI, feel free to copy-paste it as a starting point.) Importantly, and a big reason to distribute via Homebrew as opposed to a language-specific package manager, is that I could theoretically swap out the implementation for some other language entirely without disrupting users' ability to upgrade.

Key highlights if you're reading the formula contents:

  • All formulae are written in Ruby, not just Ruby-related formulae. Before JavaScript and AI took turns devouring the universe, popular developer tools were often written in Ruby and Homebrew is one of those
  • You can specify your formula's git repository with the head method (though I'm unsure this does anything)
  • Adding a livecheck seemed easy and worth doing
  • Adding a test to ensure the binary runs can be as simple as asserting on help output. Don't let the generated comment scare you off
  • Run brew style searlsco/tap to make sure you didn't fuck anything up.
  • By default, the --ruby template adds uses_from_macos "ruby", which is currently version 2.6.10 (which was released before the Covid pandemic and end-of-life'd over three years ago). You probably want to rely on the ruby formula with depends_on "ruby@3" instead

When you're happy with it, just git push and your formula is live! Now any homebrew user can install your thing:

brew tap searlsco/tap
brew install imsg

Update the formula for each CLI release

Of course, any joy I derived from getting this to work was fleeting, because of this bullshit at the top of the formula:

class Imsg < Formula
  url "https://github.com/searlsco/imsg/archive/refs/tags/v0.0.5.tar.gz"
  sha256 "e9166c70bfb90ae38c00c3ee042af8d2a9443d06afaeaf25a202ee8d66d1ca04"

Who the fuck's job is it going to be to update these URLs and SHA hashes? Certainly not mine. I barely have the patience to git push my work, much less tag it. And forget about clicking around to create a GitHub release. Now I need to open a second project and update the version there, too? And compute a hash? Get the fuck out of here.

Now, I will grant that Homebrew ships with a command that opens a PR for each formula update and some guy wrapped it in a GitHub action, but both assume you want to daintily fork the tap and humbly submit a pull request to yourself. Clearly all this shit was designed back when Homebrew was letting anybody spam shit into homebrew-core. It's my tap, just give me a way to commit to main, please and thank you.

So anyway, you can jump through all those hoops each time you update your CLI if you're a sucker. But be honest with yourself, you're just gonna wind up back at this stupid blog post again, because you'll have forgotten the process. To avoid this, I asked my AI companion to add a GitHub workflow to my formula repository that automatically commits release updates to my tap repository.

If you want to join me in the fast lane, feel free to copy paste my workflow as a starting point. The only things you'll need to set up yourself:

Now, whenever you cut a release, your tap will be updated automatically. Within a few seconds of running git push --tags in your formula's repositories, your users will be able to upgrade their installations with:

brew update
brew upgrade imsg

That's it. Job's done!

The best part

This was a royal pain in the ass to figure out, so hopefully this guide was helpful. The best part is that once your tap is set up and configured and you have a single working formula to serve as an example, publishing additional CLI tools in the future becomes almost trivial.

Now, will I actually ever publish another formula? Beats me. But it feels nice to know it would only take me a few minutes if I wanted to. 🍻

While I'm complaining about LLMs, another one: the overwhelming preference for creating dead code by keeping around old code paths "for compatibility" in case anyone depends on it, despite their being not only duplicative but literally unreachable. Another searing indictment on the incompetence of the countless professional programmers whose work served as training data.

Copied!

One of the most pernicious habits of LLMs (that I can simply never get them to stop doing) is to sprinkle in useless code comments everywhere. No amount of prompting or instructions ever really helps.

Says a lot about the code they were trained on.

Copied!

GPT-5 + Codex is so fast that when I expressed suspicion that a script was returning too few results (via | wc -l), Codex corrected me that I should have passed --count instead. Sure enough, that worked.

Checked git status and realized Codex implemented the --count flag in the script concurrently as it corrected me for not having used it! Gaslit by a robot!

Copied!

You won't believe this Codex fork

Reddit turned me onto this just-every/code fork of OpenAI's Codex CLI last night. Since it uses the binary name coder to differentiate it from code and codex, I guess we should just call this thing Coder.

In addition to everything you get with Codex:

  • A built-in diff viewer (Ctrl+D). If you're like me, you often have Claude Code or Codex open in one window and your preferred Git UI (I use Fork) in a second window, so having it integrated is wonderful. Moreover, while viewing a diff, you can press e to request an explanation of the specific change you're looking at
  • Built-in browser support with ASCII previews (Ctrl+B) Like Playwright, it automates browsers over the very fast CDP, and it takes zero futzing to get started with it (unlike tacking an MCP tool onto Claude)
  • Multi-agent consensus If you're a real sicko, you can hand the same question or task to all three of GPT, Claude, and Gemini and keep the consensus winner among them

Coder also has a themeable, more stable curses-like UI (as opposed to top-level terminal scrollback). It's the rare case of a community taking a heavily-funded corporate open source project and adding a lot of visual flair and spit polish to it. But I'll be damned if this isn't a much nicer experience than either Claude Code or Codex out of the box. (I can't speak to OpenCode, but since it doesn't support ChatGPT subscriptions, I'm not interested in it.)

From my friend Anthony Salamon on what it's like to win an award in the film industry:

The psychology of winning is also more complex than anyone admits. There's an immediate high, followed by a weird emptiness. You've achieved something you've been working toward, and suddenly you need new goals. Some winners describe a mild depression that follows major recognition, the "What now?" syndrome that comes when you realize that achieving your dreams doesn't fundamentally change who you are or solve your deeper creative challenges.

In my experience this phenomenon extends to any achievement or event that redounds to a significant moment of extrinsic validation in one's career. Anthony's description of the hangover effect following an award win mirrors exactly what it felt like to give a big conference talk or keynote address, especially if it was a "first" for me and doubly-so if it was very well received. It was always followed by a brief and intense emotional high followed by a deep well of uncertainty and exhaustion. A lesson I learned every conference season and promptly unlearned just in time for the subsequent year's conference season.

Speaking of conference season, I retired from speaking a year ago and it's that time again. Rails World is this week and lots of my friends are in Amsterdam and I am experiencing absolutely no FOMO. Don't miss it at all. Few things are as intrinsically validating as accurately forecasting how a consequential decision will ultimately make you feel. Zero regrets.

An insightful take from Hugo Tunius that makes a distinction between sideloading apps and controlling what software runs on "hardware you own":

When Google restricts your ability to install certain applications they aren't constraining what you can do with the hardware you own, they are constraining what you can do using the software they provide with said hardware.

To wit, if you own your iPhone outright, it's completely reasonable to demand that you be able to boot an alternative operating system and, to whatever extent regulatory action against the platform holders is warranted, it should be targeting this layer of the software stack as opposed to mandating how specific features of the operating system ought to function.

Which means the remedy would look a bit like the surprisingly-successful Right to Repair movement:

However, our critique shouldn't be of the restrictions in place in the operating systems they provide – rather, it should focus on the ability to truly run any code we want on hardware we own. In this context this would mean having the ability and documentation to build or install alternative operating systems on this hardware. It should be possible to run Android on an iPhone and manufacturers should be required by law to provide enough technical support and documentation to make the development of new operating systems possible.

A "Right to Run" movement that demanded hardware vendors enable their devices to run unsigned operating systems—and to perhaps provide documentation and device drivers—seems to me like it would stand on far firmer legal and conceptual ground than the knots the Europe Commission has tied itself in trying to enforce the Digital Markets Act.

Of course, pragmatist regulators would point out that approximately abso-fucking-nobody would go to the trouble of running "Linux on the phone," because of how miserable an experience it would be relative to using the default operating system. And the platform holders would justifiably cry foul that criminals and state actors could effectively rootkit people's devices and gain an unbelievable amount of surveillance and control over their lives. But there's no form of freedom that doesn't pose these sorts of risks.

Anyway, interesting idea.

Breaking Change artwork

v43 - The Slop Economy

Breaking Change

Video of this episode is up on YouTube:

Remember it is your civic duty to e-mail me at podcast@searls.co. As of this episode, that address is monitored by Fastmail, so there's a higher probability I'll actually get your e-mail!

Some links you won't click:

Show me them show notes…

Pro-tip: the codex CLI can't search the web by default (even if you bypass all sandbox restrictions). You need to explicitly enable --search.

If you ask codex to search the web without that flag, it'll literally guess domain names and try curling their homepages.

Copied!