Coding on your own machine is a little intoxicating. Everything just works. You control every variable, nothing surprises you, and the whole thing hums along exactly like you designed it to.
I’d been building ThunderSweep, a Chrome extension that scans your Gmail attachments for sensitive documents. Old tax returns, bank statements, anything with a social security number buried in a PDF you downloaded once and forgot about. I built it to run entirely inside your browser: no cloud, no servers, nothing leaving your machine. The logic was solid. The UI was clean. I ran the final test on my laptop, watched it scan my inbox exactly the way I’d planned, and leaned back feeling very satisfied with myself.
I genuinely thought I was 99% done.
That was a mistake.
The first thing that fell apart was the payment integration. I picked one I’d never used, assumed the approval process was just some automated checkbox thing, and mentally moved on before I’d even hit submit.
First rejection: no website. I had a domain. I just hadn’t put anything on it. I was so locked into building the actual extension that I’d bought the URL and then immediately forgot it existed. That meant stopping everything, building a landing page from scratch, and resubmitting.
Second rejection: they needed a demo video to verify the product.
I write code. I am not a video person. The last time I edited anything resembling a video was probably a school project. But the platform required it, so I spent most of a day scripting it out, recording my screen, and then fighting with video editing software in a way I can only describe as being slowly ground down. I got something I was actually okay with, uploaded it, and hit send.
Then I got a rejection email without any specific reason at all. I wrote back asking for clarification, waited another whole day, and got absolutely no reply. My timeline was slipping, and I decided I wasn’t going to just sit around waiting. I swapped to a different payment processor entirely, which meant ripping out and rewriting the whole license verification system. Rewriting the whole thing from scratch was more work, but at least it was work I controlled. Being rejected with no explanation meant waiting on someone else’s timeline for a reason I didn’t even understand. I’d rather rebuild than sit there.
Once payments were actually working, I ran into the Google authorization issue, which took me an embarrassingly long time to realize was entirely my own fault.
ThunderSweep has to request permission to read your Gmail attachments, so it has to go through Google’s OAuth review process. I’d spent a few days getting the authorization flow set up, tested it constantly, got it working cleanly. Submitted to the Chrome Web Store. Waited.
The reviewer came back saying they couldn’t log in at all.
I tested it myself immediately. Worked fine. I sat there genuinely puzzled, going through the code looking for something wrong, before I finally dug into the Google Cloud settings and found it. OAuth apps start in “testing mode,” which means only accounts you’ve manually added to a whitelist can authorize them. My testing email was on that list. The reviewer’s was not. It worked perfectly for me every single time because of course it did.
I was the only person on earth who could use this app.
I had to update the settings, resubmit the whole package, and send an apologetic message to the reviewer explaining that I’d accidentally locked them out of my own product. Not a great look.
The resubmission went through without a problem. The reviewer logged in, the extension worked, and I got the approval. Anticlimactic after everything, honestly. No big moment. Just an email.
What hit me afterward was that none of the things that nearly derailed this launch had anything to do with the actual product. The scanner works. The privacy architecture is solid. Everything I spent months building performed exactly as designed. What almost sank it was forgetting to put up a website, not knowing how a new payment platform’s approval process worked, and one toggle I’d never thought to check. The technical work was the easy part. I genuinely didn’t expect that going in.
Nobody teaches the deployment layer
Every tutorial, every course, every deep dive I’d ever watched stops at “it works on my machine.” What comes after that, the platforms, the approvals, the policies, the review boards, apparently you just have to walk into face first and figure it out. Which I did. Repeatedly.
And now that the extension is actually live, I’m staring at what is probably the hardest part of all: getting anyone to actually use it. I know nothing about marketing. I’ve never tried to sell something I built. My instinct is to just go back to writing code, which is comfortable and makes sense to me. But that’s exactly the kind of thinking that had me launching a product with no website.
So I’m staying in the discomfort. I’ll figure out marketing the same way I figured out everything else on this list. Badly at first, then less badly. There’s no version of this where I already know what I’m doing.
Follow the Journey
If you want to watch someone stumble through OAuth configuration, marketing strategies, and trying to get a privacy-focused product from 0 to 1, subscribe to my Substack. I share every mistake and win along the way.
Subscribe on Substack