I built PMP Pulse: an anonymous team survey in one evening
I’ve caught myself trying to figure out who wrote the uncomfortable survey response.
Team of 30. Someone mentions that onboarding is confusing. My brain immediately starts doing the math. Who joined recently? Who complained about this in a 1-on-1? Who uses that phrase?
Most founders have done this. We just don’t say it out loud.
That’s the problem.
Not “we need a better survey tool.” Not “Google Forms has bad UI.” The real problem is simpler and uglier. People don’t feel safe telling the truth at work. Especially on remote teams. No hallway chats, no coffee machine, no human glue. Just Slack messages and Zoom windows and the quiet suspicion that if you say the wrong thing in the wrong form, it will find its way back to you.
And once people feel that, your survey is dead. Doesn’t matter how pretty it is. Doesn’t matter what vendor you use. Doesn’t matter how many times you write “anonymous” in the intro copy.
If people don’t believe it, they won’t tell you anything useful.
The “anonymous” lie every SaaS tool tells
Every survey tool has the word somewhere on its marketing page.
On a team of 30, “anonymous” and “your manager can’t figure out who said this” are two completely different things. Your team knows it. They feel it even if they can’t explain it. That’s why answers cluster in the middle. That’s why the same four people say the same four safe things every time.
We already use Google Forms for other surveys. I looked at it for about ten seconds. Bad UI. No real admin panel. No aggregate scoring. Weak email notifications. And worst of all, it’s Google. Everyone assumes Google is quietly logging who they are. Not exactly the vibe when you’re asking for honest feedback about management.
So I did what any reasonable person does at the start of a free evening.
I opened Claude Code. Cursor was already running. And I started building.
No spreadsheet comparing tools. No vendor calls. No build vs. buy workshop. I wanted to experiment with Hono, get more reps on Cloudflare Workers and D1, and the problem was real enough that the playing felt justified. The fun reason and the practical reason showed up together and walked in holding hands.
What I actually built
PMP Pulse. A dead-simple anonymous internal survey tool for Painter Marketing Pros.
Monthly pulses, quarterly deep dives, ad-hoc surveys. One question at a time, instead of one long scrolling form that makes people feel like they’re filing their taxes. Review step before you submit. Aggregate scoring so trends show up over time. CSV export. Email notifications.
The respondent experience matters more than most people think. Long forms kill completion rates. They also let people anchor their answers against each other, scrolling back to see what they said in question three before answering question fifteen. One question at a time forces engagement in isolation. Keyboard-first. Hit 1 through 0 for ratings. Auto advance in 1 sec or press Enter to advance. The whole thing works without touching a mouse.
Admin side: magic link plus OTP login. No passwords. Clean dashboard with summary statistics, individual response views, and a CSV export that drops straight into Sheets.
That’s it. That’s the whole product.
The stack (and what it costs)
Claude Code and Cursor as the dev toolkit. First working version in about two hours. Everything after that was iterative polish, which is how these things always go. The first 80 percent arrives fast. Then you spend another two hours deciding how a button should feel.
One Cloudflare Worker. One D1 database, SQLite living at the edge with reads under 10ms. Hono for routing. TypeScript in strict mode. Resend for email. Cloudflare Turnstile for bot protection. Server-rendered HTML with about 200 lines of vanilla JS for navigation, keyboard shortcuts, and form behavior.
No React. No Tailwind. No component library. No build step circus. Just HTML, CSS, TypeScript, and a database.
Under 2,000 lines of TypeScript total. The whole bundle ships at around 38KB gzipped. Marginal cost per quarter: exactly $0. Everything fits comfortably inside Cloudflare’s free tier. Resend’s free tier easily handles the notification volume. We use paid Cloudflare Workers and Resend, but this tool wouldn’t need them.
For a small internal tool, that’s hard to beat. Nobody should be paying a monthly fee for software that promises anonymity it can’t keep. This is how AI is changing SaaS. 2 years ago, I might have stuck with Google Forms or Typeform instead of spending days building something of my own. AI has reduced the time these small tools require to almost zero. This is what is changing SaaS.
The architecture of honesty
Here’s the part that actually matters.
Genuine anonymity isn’t a promise. It’s a design constraint.
There is no user_id on any response row. No foreign key to any identity table. No login on the respondent side. Given a submitted response, there is mathematically no query I can write that connects it back to a specific person. The database has no user table to join against. A response is just a floating row with a timestamp and the answers. That’s it.
I didn’t just build anonymity for the team.
I built a cage for my own worst instincts and shipped it as an internal product.
Because the temptation is real. I know it’s real because I’ve felt it. An uncomfortable response lands, and your brain starts running the correlation engine before your values have even put on their shoes. Who said this? Who’s upset? Who used this phrase in a Google Chat message last week?
Most people talk about anonymous feedback as if the danger were that the employee would lie. I think the bigger danger is the founder or managers getting curious. That’s the thing nobody says.
So I built the system to protect the team from me and the management. Not with a promise. With a hard constraint. You cannot trace this back because there is nothing there to trace.
Sometimes the custom tool is the simpler option
Google Forms wasn’t rejected on features alone. It was rejected because “it’s Google” means Google knows who you are. On a team of 30, that’s not abstract. That’s the whole problem.
The custom build wasn’t more complex. It was simpler. One Worker. One D1. One Resend account. No vendor to trust. Just a thing that exists now because the problem was real and the evening was free.
Three honest questions before you open the terminal:
If you are also like me and want to use AI to build your own tools, the three questions to ask before you fire up your AI agents are:
- Is the existing tool architecturally broken for your actual need? Not missing a feature. Broken at the design level, in a way that no pricing tier fixes.
- Can you scope it to one evening before it becomes a six-month project nobody asked for?
- Are real users showing up Monday, or are you building for ghosts?
Two out of three and you’re probably fine. Zero out of three and you’re building a printing press to write one sentence.
The team will use PMP Pulse this month. They’ll be honest or they won’t. But the system can’t betray them even if I get curious on a random Tuesday.
That’s the whole point.
I built a constraint on myself and called it a product.
~ aq