I paid people to try and follow my README
349 points - today at 11:47 AM
SourceComments
I sometimes write readmes for myself, so that I can remember the exact steps to generate a data report, etc.
It's surprising how much they become incomprehensible after just a couple of weeks; when everything's in our head it's all clear, fluid and self-explanatory; but once we have forgotten the context, nothing makes sense anymore.
Half the posts I see lately are like, "Gleam 2.0. What we learned" and then you go to the homepage and it's "Gleam is a Tribble for your Fork! (Scroll down) See if you qualify for Gleam Enterprise!"
The Nielson Norman Group has a good introduction to this: https://www.nngroup.com/articles/usability-testing-101/
Is this interesting to people on HN?
I majored in a mix between coding and design.
I cannot tell you how many READMEs I've read that follow the pattern: "<uninformative-name> is a <buzzword> <buzzword> written in <language>." I only have some semblance of what it does after using/seeing a demo; too often one that isnt available through the README.
I write docs that AI agents have to follow to play a game through an API, then spin up 20 sub-agents each with their own identities / properties etc. and watch where they fail. They get stuck in the same places as humans.. or they will point out the "obvious" steps not explicitly mentioned.
now where the AI tests start to fall apart is that an agent doesn’t tell you the doc is confusing, it just does something wrong with full confidence. A person on a call says “wait, what?” and that’s worth the 25 euros :)
I used to write technical documents in prose style, sometimes with meandering stories. I guess I picked it up from my early blogging days. I realized I hated reading some of them back. So I tried to keep it cut and dried. I do sometimes sprinkle a bit of colorful wording just to add a bit of humanity but only if it doesn't get in the way of the main message.
It seems to be taken for granted — that's something you'd already have in place if you're already serving applications in PHP, but would have to figure out on your own if you haven't served anything in PHP so far in your life.
Even if it is a command-line tool, a screenshot helps provide a better understanding of what to expect.
I think good technical writing requires the same skills as good product ownership, that is empathy for the user and their perspective. Often technical writing is an after thought and not someone’s whole role and it really shows.
Good article
Update: Found some related HN threads (omitted link-rotted submissions).
- I'd like to review your README https://news.ycombinator.com/item?id=26842191 (91 comments)
- Readme.so – Easiest Way to Create a Readme https://news.ycombinator.com/item?id=27006740 (65 comments)
- Readme Driven Development https://news.ycombinator.com/item?id=1627246 (57 comments)
Each phrase or sentence is an operation that changes the state. The state is the mind of the reader. For it to work, you have to understand the starting state, and then construct a valid sequence that modifies the state step by step until it reaches the desired state. Every step has preconditions and postconditions. You can't leave important values uninitialized. You can't refer to symbols that haven't been defined. You can't just sit down and blurt out whatever comes to mind; you have to "play computer" (or "play reader") in your head to model the effects of what you're writing. You need to be aware of which "platform" you're targeting (developers, users) and understand quirks of each variation of that platform. Some of your operations might fail, and you may need a way to detect and/or recover.
Obviously don't take it too far and reduce writing to this. But I think it's helpful for getting into a mindset where you are thinking about communication in an end-to-end, closed-loop way. Your mind needs to be engaged and stay engaged with the question of what the experience is like for the reader. It's very easy to default to an open-loop mode where you just have a random string of thoughts about the subject, let your brain translate them into words, write that down, and call it done. There's a big difference between expressing thoughts and communicating ideas effectively.
Thinking about it this way could also maybe help with motivation. It's satisfying to write computer code and really nail it and have it do its job effectively, right? You can get a similar feeling of satisfaction from good writing.
This was generally really a good way to go about it, because it requires everything to be correct with no room for adjustment.
Still people would miss things, but it always came from skipping instructions (sometimes completely.) Maybe 10 support inquiries total.
2real4me
In all seriousness tho, I don't really put jokes in readmes or code comments. Jokes should be tied to a moment where they make sense, not just be present in perpetuum. Slack is great for jokes, or maybe even a notion design doc comment, alongside the actual feedback.
But sticking jokes in your readme just feels like "I have you here for other reasons, now you have to listen to me be funny".
I oftentimes find myself spending more time rewriting readmes than writing code.
Treat the readme like a journey/walkthrough of your product, follow an order, and keep it simple to understand.
I build apps with Claude Code, and I test them by having the AI click through the UI with Playwright. That's enough to check that things work as specified and nothing is broken.
But I think the purpose is different when an AI tries it and when a person tries it. To put it in extreme terms, AI is for UI and people are for UX. People find UI problems too, though: in my music player, songs got blocked from playing in Safari on a real iPad, and I only found it by using it myself. The things found in this article, like the jokes that didn't land or not knowing what the tool even does, are on the side only people can find.
(I wrote this in Japanese and used AI to translate it.)
I've great success with friction logs: https://mikebifulco.com/posts/how-stripe-uses-friction-logs
If you are a platform team, going through this with your internal customers is both driving adoption and making your tools better. Highly recommended!
My way in to WordPress support back in 2004 was decoding answers to others from Photomatt and others.
A user would ask a question about WordPress and, for example, Photomatt would answer. His answer was always correct. Technically correct. But it didn't land for the question asker. They would reply with .. 'What?'
I would then replay with "What Matt has said is right, and this is what he means, this is the answer"
I gave them the information they needed in words they could understand.
It was not Matt's fault, it was not the user's fault.
It was translating in a way.
Nice, good article lol. I appreciate a joke or two in a readme but totally understand the annoyance, I think forgetting to actually say what the software does is super common as well though. Often trying to figure out if something found on github will actually solve a problem only to be met with a list of install commands.
Also, it features an FAQ. FAQs are problematic (as in not often effective): https://passo.uno/what-the-faq/
Edit: Clarification
Point new starter at the readme and get them to fix any issues (hopefully very few!).
All people creating, need to speak to other people. Loved reading this.
Create a new container or sandbox, copy in the git repo or point it at your staging docs, and see what happens.
E.g. as someone who doesn't "Fediverse", the intro section leaves me having no idea what an ActivityBot is or what an ActivityBot account is.
You didn't have to murder me like that!
This is my #1 annoyance when looking at a trending repo
:’)
It feels like like the AI agents can't help themselves sometimes, and the judgement exercised around what's included and omitted is baffling.
But maybe READMEs have always been this bad, and AI agents have raised the baseline?
Closed. You are on a machine right now as am I, lets not pretend we don't like them for clout.
I just find it a bit misleading that you’re saying you want to talk to real people all while trying to clean up AI slop.
Confession time.
I used to be prone to giving things slightly silly names, particularly unrecoverable structured exceptions. Examples include PancakeLandingException, ReallyBadException, CataclysmicException, ApocalypticDeathException, and the like.
And then years and years ago I used to work for a company called Redgate and I started a tradition of slightly silly messages when early access builds of our .NET products would expire, all based on Monty Python sketches and quotes. So, obviously, the dead parrot sketch featured in there.
So far, so harmless, but this did come to a head somewhat spectacularly and in a couple of different ways.
Firstly, in 2009 one of my colleagues used a modified quote from The Life of Brian as an expiry message on a build. Somebody who appeared to be some sort of religious zealot complained loudly to the company. We were both in LA at the time, with a couple of other colleagues, attending build 2009, so we woke up to a chain of something like 50 panicked emails in our inboxes with people expressing differing levels of outrage and/or amusement whilst discussing various grovelling apology options... until someone figured out that it was actually an elaborate troll that we'd swallowed hook, line, and sinker. I can't remember the name of the person who caught us out but, hats off, well played, sir, well played. It did unfortunately mean we became a bit more cautious and business-like with our early access build expiry messages.
Secondly, and this one needs a bit of context setting... I've always been a fan of descriptive and explicit error messages: there should be enough information in any error message that most of the time the user can figure out what's wrong and fix their own problem OR at least so that if they get in touch with support, then support can quickly figure out the problem and get back to them with a solution. I'm not a fan of unhelpful, information poor, obfuscatory, or cryptic error messages.
But when I wanted to cause an application to exit because there'd been an error related to tampering with our licensing code I played somewhat against type. I wanted error messages that would uniquely identify what had happened, making it easy for us to figure out, whilst giving the user no clue (because I wanted to make it very slightly harder for hackers/crackers - but let's be real: this would never have actually stopped anyone). So I used successive lines of dialogue from a scene in House where House is trying to guess who Wilson's girlfriend is. I have no clear recollection of why I chose this dialogue to reproduce, but... I did.
Anyway, this did lead to some slightly confused support requests coming in from users mostly trying to use the tools legitimately in slightly unusual scenarios, but nothing that was overly burdensome. That was until early 2011, when Greg Young - he of event sourcing fame - posted the following gist because he'd encountered an error that said, "Because I wanna ask you about your girlfriend. I must know who she is, or you would've told me her name.": https://gist.github.com/gregoryyoung/871736.
Not at all creepy, right? And, of course, it went viral on twitter. Cue another massive email thread although, this time round, people just thought it was funny. However, we did decide to make the error messages a bit more boring and, in the end, I just gave them numbers.
Mostly I'm just glad the error Greg got wasn't the final line of dialogue in the exchange between House and Wilson: "Yo mamma." That would have been bad.
It is under 5 minutes to write a shell/bat/make/cmake script for each platform to configure library requirements, import OS specific data, and enable GPU/NPU features. Then run through the application build, installation package with stripped performance build, and or a few regression tests.
Lets say you have 4k downloads a month on a small project, and it takes 1 hour for each admin to read/configure. You just saved about 5 years of your users lives reading your document. =3
For God's sake, this is not "biases," wtf?? That's straight up just not reading/following the document you're supposed to be testing/reviewing. When I test my documents I actually follow them exactly, step by step, and I always catch these sorts of mistakes. Always. I always copy/paste commands because I know that is what the customer will do, so I have to make sure that works flawlessly.
Dude, if you actually follow your own document, you don't have to pay people to do it for you. Also, you can make sure the person you are paying doesn't ignore the document like you apparently do.
I stopped reading, I'm not interested in whatever else this dude has to say. I'm literally flabbergasted.
Maybe it's because my documents have always gone to real paying customers who have to get through this install, and not some hobby project I'm super proud of or whatever and I don't think I'm super clever? Idk.
Having said that, I found consistently that when a project has working examples, ideally documented a bit, aka explained, they tend to work much better than those projects that have no examples. Working examples often also help get into a project quickly and check out how it works. It helps to learn too.
READMEs are not useless, of course, but the quality varies a lot. I also know of folks who use AI slop spam to improve it, but while it may improve a little bit, it generates a lot of horribly to read text that makes no sense. I am noticing this with the ruby core dev team - they (almost) all suddenly have perfect language skills but it is more like an advanced babelfish translator. What they piece together here makes no sense. Claude in particular is now famous for this slop content. And I don't understand what it is used: real people read any of this AI slop? Because I just skip it or filter it away these days.
So what the author actually paid for was to interact with humans and the README checking was secondary - because, really, my own first thought was literally to ask an LLM check and try to follow the instructions in the README and pretty much any decent LLM (including several local ones) would be able to check if they're adequate and even suggest improvements (just don't let them write it for you :-P).
I know, I know: It's complicated. But have you heard of AI agents?
But I just onboarded 4 interns on a project where all they had to do was
1. Install the Nix package manager
2. Install direnv, enter the project repo, and `direnv allow`
3. Toolchain, git hooks, MCP servers, in-repo issue tracker, everything is available
Our project manager requested information that was available in the issue tracker. I told her, she could get all her answers by asking our agent, and it'd automatically reference the issue tracker. I figured I'd just need to show her how to install the Nix package manager. But no, she already had it because another project by another team depended on it.Putting wrong information is README is so outdated when you have programmatic setup of your entire toolchain.