from/prod
← All companies

THE COMPANY INDEX TRACKED BLOG

Evan Hahn

Ideas, decisions, and lessons from the team.

evanhahn.com (opens on the source site)
13Posts tracked
2 weeks agoLatest publication
1.1Posts / month over the last 12 months

Latest writing

13 of 13 posts

Notes from September 2026 (opens on the source site)

If you follow my monthly roundups, (1) who are you?? please say hi (2) you’ll notice a smaller post this time. September was a busy month for me. Lots of feedback on a small post I published “Anecdotally, programmers dislike ‘reduce’”. I finally wrote up a phenomenon I’ve observed for years. It’s a short post that didn’t take long to write. I got a tremendous volume of feedback—more than anything I’ve ever written. Dozens of messages, hundreds of comments, shoutouts in popular newsletters…I’m even meeting up with old friends because of it! This industry, for better and worse, is moving away…

Read at the source

Anecdotally, programmers dislike "reduce" (opens on the source site)

In short: from my experience, people like map and filter, but not reduce. I use functions like map and filter all the time. When I put that code up for review, my peers rarely complain. I get plenty of feedback about other decisions, but not about my use of map and filter. I cannot say the same for reduce. Often, when I’ve submitted a patch with reduce inside, I get a comment like, “this part is hard to read.” And I see reduce way less than map, filter, some, and so on. Anecdotally, I have come to believe that programmers don’t like reduce as much. I don’t know why, but I have a few theories:…

Read at the source

Notes from August 2026 (opens on the source site)

Since last month, I released some new stuff at work, clicked a bunch of links, and wrote a little bit. Things I did this August At Ghost, we added analytics for automated email sequences. This helps publishers see how their sequences are doing. This simple feature turned out to be pretty tricky under the hood. Learned that Vim has a joke trigger called UserGettingBored. I continued to write for Zelda Dungeon, including an interview with a very cool ROM hack developer. Links I clicked “Libertarian futurists weren’t the only people proposing new rules for cyberspace; they just happened to be…

Read at the source

Vim's UserGettingBored autocmd (opens on the source site)

In short: Vim has a joke autocmd called UserGettingBored that doesn’t do anything. Vim’s automatic commands feature, usually shortened to “autocmd”, lets you run code when various events occur. For example, you could implement an auto-save feature by binding the TextChanged event to the :w command. Vim has over 100 events, from “buffer was created” to “file was saved”. But one of them sticks out to me: UserGettingBored. Here’s the documentation: UserGettingBored: When the user presses the same key 42 times. Just kidding! :-) When I saw this, I was busy doing something else and it completely…

Read at the source

Notes from July 2026 (opens on the source site)

July! What a month! Things I did this July Gave a talk, for ClimateAction.tech’s “Responsible AI Series”, “What I know about local language models”. “Responsible AI” can feel like a bit of an oxymoron at times, but I hope I shared something useful. Participated in the Zelda Dungeon Marathon. My first time playing a video game (The Legend of Zelda: Oracle of Seasons) on stream! Released a new version of Helmet, my Node security headers package. Most notably, it sped up the Content-Security-Policy code by about 7% for common cases. Promoted an underrated SQLite feature: strict tables. Wrote a…

Read at the source

Prefer STRICT tables in SQLite (opens on the source site)

In short: I prefer strict tables in SQLite because they avoid some datatype problems, such as putting text in number columns. SQLite has a feature that I think is underrated: strict tables. Strict tables help enforce rigid typing, preventing mistakes like putting text into integer columns. I like them, and wrote this post to promote their use! To make a strict table, add STRICT to the end of its definition. Like this: -CREATE TABLE people (name TEXT); +CREATE TABLE people (name TEXT) STRICT; That’s it! But what does it do? Advantages of strict tables Broadly, strict tables help enforce rigid…

Read at the source

Notes from June 2026 (opens on the source site)

Chicago’s weather is pretty lousy most of the year, but when it’s nice, it’s very nice. June blessed the city with dozens of idyllic days. But don’t worry—I still spent most of the time inside on the computer. Things I did I launched my first big project at Ghost: automations! It’s still in beta, but it’s one of the biggest projects I’ve led. If you happen to be a Ghost publisher, please try it out and let me know what you think! For the sixteenth issue of the Taper online magazine, I visualized time by breaking each unit into sixteenths. For example, as I write this, I’m about 6 sixteenths…

Read at the source

"Sixteenth of a year", a 1.8 KiB art piece (opens on the source site)

As I write this, we’re about 7 sixteenths through 2026, and it’s about 14 sixteenths through the day. For the sixteenth issue of the Taper online magazine, I split time into sixteenths to think about its passage in a different way. The code, which had to be under 2048 bytes, isn’t terribly complex. It does some date math and uses a Go server for minification. If you want, here’s the unminified source code. Go check out all the other entries from this issue! My favorites include "[SIC]", “Desperate Measures from a Dying Regime”, and "(un)done". See also: my previous Taper entry.

Read at the source

Notes from May 2026 (opens on the source site)

My blog turned 16 this month! I did nothing to celebrate, but made some little tools and clicked some links about tech ethics. Things from me this month I published four little tools this month: ZIP Shrinker, a web app that shrinks ZIP files with higher compression ratios A command line tool to do (completely offline) translation Open Link in Unloaded Tab, a Firefox extension to open links without loading them png-cmp, a command line tool to compare PNG pixel data I also did some work on Helmet, my open source project: After over a year of quiet maintenance, I released version 8.2.0 with some…

Read at the source

Make ZIP files smaller with ZIP Shrinker (opens on the source site)

I built ZIP Shrinker, a little browser tool to shrink ZIP files. It also works with formats that are secretly ZIPs underneath, like EPUB, JAR, and many more. Try it out! How does it work? At a high level, this tool (1) re-compresses every file in the ZIP archive with higher compression (2) removes all metadata (3) removes entries for directories. Re-compressing ZIP files are typically compressed with an algorithm called Deflate. There are a few tools that can re-compress Deflate data and make it smaller, usually by spending more time on the computation. I took one of these tools, libdeflate,…

Read at the source

Open Link in Unloaded Tab, a little Firefox extension (opens on the source site)

In short: I just published Open Link in Unloaded Tab, a little Firefox extension that adds “Open Link in Unloaded Tab” to the right-click context menu. In Firefox, you can unload tabs to save system resources. But there’s no way to open a new tab in the unloaded state…until now! I built a very simple extension that adds a new option to do this. (It even has a cute icon which I paid ~$15 for.) I’ve built one-off extensions before, but this is the first one I’ve submitted to the Firefox Add-ons directory. Download the extension here or check out the source code.

Read at the source

png-cmp: like cmp for PNGs (opens on the source site)

png-cmp is a program I built that checks if two PNGs are visually equivalent. It’s inspired by the cmp command. Here’s how you use it: png-cmp a.png b.png Like cmp, it silently exits if the images are identical, and gives an error if they’re different. Unlike cmp, it checks pixel data, not binary data. PNGs can look the same but be stored differently. For example, png-cmp ignores text metadata. I was recently doing an experiment where I wanted to check if two PNGs were visually identical, so I built a tool for it! Grab the source code here.

Read at the source

Offline command line translation with TranslateGemma + Ollama (opens on the source site)

I wrote a simple script that translates text at the command line, completely offline. Here’s an example of how it works on my computer: echo '¿Cómo estás?' | translate # => How are you? It combines a few tools: TranslateGemma, a special-purpose language model for translation Ollama, a tool for running language models locally Efficient Language Detector, a library that detects the language for a piece of text Here’s the pseudocode of how it works: source = read_stdin() # Uses Efficient Language Detector source_language = detect_language(source) # Uses JavaScript's `navigator.language`…

Read at the source

Privacy choices

Reading never requires analytics. These choices last 90 days on this browser.

Essential sign-in and security storage always stays on. Read the privacy notice.