Why I Built a CLI for Thanking Open-Source Maintainers
There are open-source maintainers who have never received a single message from someone using their work. Not “this is great.” Not “thanks for saving me a week.” Nothing.
Downloads tick up. Maybe some stars. Occasionally an issue that’s really a support request. But genuine, unprompted gratitude? Almost never.
The spark
I was watching 4 hours to build a web app with Google Gemini — a Web Dev Challenge episode where four developers each build a gratitude-themed app in four hours. One of them, Zeu, built something called #ThankADev. It pulls the software bill of materials from a GitHub repo using the OpenSauced API, generates a thank-you note for each dependency with Gemini, and gives you a button to tweet it out.
I loved the idea. But it was a web app, built in a hackathon. I kept thinking about the shape of the thing. What if this lived in the terminal, where the work actually happens? What if you could thank a maintainer in 10 seconds between git push and coffee? And what if an AI agent like Claude could use it too — just another step in a workstream?
Same instinct. Different tool.
The feedback gap
Open source has infrastructure for everything except positive feedback. Issue trackers for bugs. Pull requests for contributions. Discussions for questions. Sponsorship for money. But no built-in way to just say “hey, this thing you built matters to me.”
Stars are the closest thing, and they’re silent. A star doesn’t tell the maintainer who you are, what you’re building, or why their package matters to your work.
What I built
Thanks CLI (give-thanks) does one thing: delivers a thank-you to an open-source maintainer through the best available channel. One command:
give-thanks hashbrown --used-for "generative UI dashboards for a Shopify merchant copilot"
The maintainer sees something like this:
Thanks for building hashbrown!
Hey! I’m using hashbrown in my work for generative UI dashboards for a Shopify merchant copilot and wanted to say thanks for building and maintaining this. It makes a real difference.
This message was sent using give-thanks, a CLI for thanking open source maintainers.
That’s it.
The fallback chain
The first version tried to post a GitHub Discussion, and if that wasn’t available, it stopped and asked you what to do. The problem: most repos don’t have Discussions enabled. And that interactive prompt broke agent and CI workflows.
So I replaced it with a deterministic fallback chain. No prompts. It tries the best channel first and falls through until something works:
- Star the repo — always happens
- Post a Discussion — if the repo has Discussions enabled
- Open an Issue — if Discussions aren’t available
- Send an email — if both fail and the maintainer has a public email
- Star-only — if nothing else works, you still starred it
One channel per run. No spam. The tool picks the best one and tells you what it did.
After thanking, it surfaces other ways to reach the maintainer — their public email, blog, or Twitter — so you know how else to connect.
Why a CLI
Because that’s where the work happens. If thanking a maintainer means opening a browser, navigating to a repo, finding Discussions, writing a message — nobody’s going to do it.
The other reason I care about: AI agents. If you’re working with Claude and your workflow has you pulling in a bunch of small packages — scaffolding a project, evaluating libraries, wiring up integrations — the agent can run give-thanks as part of that workstream. A CLI is the one interface that works for both humans and AI agents. Gratitude becomes a step in the pipeline, not something you remember to do later and then don’t.
The tool auto-detects non-interactive environments. If stdin isn’t a TTY — CI, piped commands, agent workstreams — it runs fully automatic. No surprises. You can also pass --non-interactive explicitly.
Scan mode
The single-thank command is useful, but the more interesting feature is scan:
give-thanks --scan
Reads your package.json (or requirements.txt, or pyproject.toml), filters out packages you’ve already thanked, and gives you an interactive checklist. Pick the ones that genuinely matter. It handles the rest.
In non-interactive mode, it skips the checklist and thanks everything unthanked — useful for CI pipelines where you want to bulk-thank on deploy.
Decisions I care about
No infrastructure. No server, no database, no account. History is a local JSON file at ~/.give-thanks/history.json. Auth piggybacks on the GitHub CLI or a GITHUB_TOKEN env var. Nothing to deploy.
Multi-ecosystem. Resolves packages from npm and PyPI, or you pass a direct owner/repo. The resolver system is plugin-based — adding Cargo or Go modules later is straightforward.
Dry run. --dry-run shows exactly what would happen without posting anything. A tool that posts on your behalf has to earn trust.
Email fallback. Some maintainers disable Discussions and Issues but have a public email. If you set a RESEND_API_KEY, the tool sends a thank-you email as a last resort. If you don’t have the key, it just logs the address so you can reach out yourself.
Channel tracking. Every thank-you records which channel was used — discussion, issue, email, or star-only. Your history shows not just who you thanked, but how.
Will anyone use this?
I don’t know. But if a handful of developers run give-thanks hashbrown or give-thanks requests and a maintainer reads that Discussion post on a rough day — that’s enough.
Open source doesn’t need more tooling. It needs more humanity.