Bernard devlog #1: MVP
The goal of this series is to document the work and effort involved in taking a software idea and building a solo and bootstrapped (i.e. with no outside investments) business out of it. While there's a lot of books and talks by people more successful than I am, for this devlog I'd like to drop the façade of unrelenting optimism of the classic American entrepreneur ("here's how I reached $1M MRR in two weeks") you can find anywhere on Twitter, and just talk straight shop, with all the challenges, failures and anxiety I experience every day trying to build Bernard.
This venture might never amount to anything, or it might make me a billionaire. Right now, it's a dream only myself and my Emacs instance are privy to, and I believe it might be worth keeping a record of it.
What is Bernard, and why do I care about this problem?
Bernard is your website's best friend. Actually, right now, Bernard is an automated broken links checker, that is, a service where you enter your website, and periodically it gets crawled in its entirety to make sure all resources, links and objects are reachable. Because 404 errors are a plague of our Internet and they suck. They make you lose customers and ruin your SEO.
But Bernard was not born a links checker. Its original goal, and the killer feature I want this product to focus on, is a service that is proactive in telling you if, after yet another redesign, you forgot to set up redirects from your old URLs to the new. Because cool URLs should not change. This is the root cause of most 404 errors, and all the clients I have worked with that have paid me to rewrite their website had no visibility whatsoever if any URL change was breaking someone's bookmarks, or sending potential customers to a Page Not Found error page, until it was far too late. Hell, over the past few months I have re-engineered this blog more than once, and more than once I broke some of the URLs. I hate it with a passion, all that effort to create decent content for a user to land in the HTML version of the Backrooms.
Bernard was born to scratch my own itch first and foremost. And I believe that there are others with that exact problem.
So, to get there, to check all links on a website, I need to crawl it in its entirety, so creating a link checker was the focus for the MVP.
The path to the MVP
I started writing the crawler code on 2 November 2022, probably a couple of hours after having the idea while doing the dishes. I always get my best ideas in front of the sink.
The crawler is a standalone Rust application whose job is to download each page, collect all links, and testing them to determine if they are working or not. While the backend and web app is written in Elixir, I chose to make the crawler a standalone process because I hoped to eventually release the thing as open-source, and while this might be a great goal to strive for, it was far too early to make that call. Spending a lot of time on ideas or systems I will not need is a recurring theme of this phase of development.
After a month, in December 2022, I started working on the backend and web interface, using Elixir and Phoenix, which is my favourite tech stack, and one I am incredibly productive with. By this point the crawler was in good shape, and I was already planning an MVP, discussing the idea with a friend of mine which is ideal target user—he runs a web agency—and thought I could get something out the door by end of January 2023.
Of mice and men
Between real life constantly taking me out of my flow zone, having to concurrently find work in the worst hiring market I've ever seen (I'm still searching. Hire me.) and the paralysing fear of seeing my GitHub issues list grow faster than I can close tickets, I have launched the MVP behind closed doors on 6 May 2023, four weeks ago.
I haven't done any marketing or publicity about this project just yet, but by mentioning this idea here and there, and on a couple of Hacker News comments, around March I managed to get in touch with half a dozen people that have expressed their interest to trying this out and have entered their email on the waitlist form.
I'll be honest, after sending these early adopters the invite email in May, 2 months after having spoken to them, only one (the friend of mine mentioned above) actually went through and created an account. That was quite painful. Understandable, but ego is a bitch, and it was not fun going from the high of "Yay, I have finally shipped!" to the crushing low of "no one actually would pay for this".
It was time for a dose of reality; now the real work begins.
To keep this post short, I'll go into the technicalities in the next devlog.
Writing code is the easy part.
Feeling like a failure, an impostor, and second-guessing your idea soon becomes a constant in your life, a voice that grows louder every passing day. Until your idea pays the bills, this is the hardest part of starting a business.
You will spend 1/3rd of your time planning and coding stuff you do not need.
Without intense marketing effort, Google does not give a crap about your website. And if you're not on Google, you do not exist.
The past few weeks the second-guessing, paired with the utter exhaustion of finding work and something that pays the bills, haven't been kind to my mental health, but I am now ready for the second part of this journey. I was also waiting for Paddle, my Merchant-of-Record and payment processor, to approve my account. After only a month, I got carte blanche from them last week, so I can now focus on launch ASAP.
That means taking care of the last 20% of the work, polishing, and, if Pareto is to be trusted, it will take as long as writing the code in the first place. I'm considering to throw the crawler in the bin, replacing it with a new one in Elixir that leverages the power of the BEAM. That might be a good topic for the next devlog, unless I change my mind yet again and decide to stick with the Rust one until after launch. We'll see.
I'm not planning on making a great ceremony out of launch. I just want to get to the point that I am mostly comfortable for people to enter their credit card number, and then, finally, the long road to growth and to acquire the first paying customer starts. I feel that is the only obstacle before I see this as an actual business and not a hobby I have invested way too much time and money on.