There’s a job that turns up on every single project, every year, forever. It arrives right at the end, after the hard thinking is done, after the design is signed off, after everyone has finally agreed on the words. Someone says, almost as an afterthought: “oh, and we’ll need a contact form.”
And every time, you have to have the same slightly awkward conversation.
The problem that wouldn’t go away
Static websites are wonderful things. This very site is built with Hugo - it’s a stack of plain HTML files sitting on a server somewhere. It loads instantly, it costs almost nothing to host, there’s no database to leak and no admin panel for someone to guess the password to. For a huge number of businesses, it is genuinely the right answer.
Right up until you want someone to be able to email you from it.
Because the moment you add a form, you need something to catch it. And “something to catch it” means a server, which means an SMTP relay, which means a place to store submissions, which means patching, monitoring, a monthly bill and a thing that can quietly stop working at 2am on a Sunday without telling anybody. You’ve just taken a beautifully simple website and bolted a small, permanently hungry animal onto the side of it.
So you end up choosing from a fairly grim menu:
| Option | The reality |
|---|---|
| Spin up a little server for it | Now you own a server forever, for one form |
| Use one of the big form platforms | Fine, until the pricing changes or you’re paying for features you’ll never touch |
Just use a mailto: link | Opens the customer’s mail client, which they may not have set up. Enquiry lost. |
| Don’t have a form | The cheapest option, and the one that costs you the most |
We solved this over and over for clients. Every time slightly differently, because every time we’d learn something and do it a bit better, or because the last project’s approach didn’t quite fit. And the fifth time I found myself copy-pasting a function from a previous job and swapping out the email address, I finally clocked it.
That’s the tell, by the way. If you’ve solved the same problem five times and all five solutions were different, you don’t have a recurring task - you have an unbuilt product.
So we built the boring version on purpose
Static Contact does one thing: it turns an HTML form into an email in your inbox. You build the form, you paste a snippet into your page, submissions arrive. No server, no database, nothing to maintain.
That’s it. That’s the whole pitch. And keeping it that small was by far the hardest part.
What we actually learned
Spam is the product
This was the big one, and I’m slightly embarrassed by how surprised I was.
I went in thinking the product was “form goes to email”. It isn’t. Anyone can write the code that turns a POST request into an email - that’s an afternoon. The actual product is deciding what not to deliver.
Within days of the first live form going up, the bots found it. Not a trickle either. If you’ve never run a public endpoint before, it’s genuinely startling how fast the internet’s automated underbelly notices a new door and starts rattling the handle. So we built Botbuster, our own filtering layer, and then added support for the good third-party options too - ALTCHA, Cloudflare Turnstile, Friendly Captcha, reCaptcha and hCaptcha - because different people trust different vendors and that’s their call to make, not ours.
And it drove a pricing decision I’m quite proud of: spam never counts against your quota, on any plan. Charging a small business for abuse aimed at them is a rotten deal, and once you’ve seen the volume, you can’t unsee how rotten it is.
The free tier is a design decision, not a marketing one
Free gets you 50 submissions a month and one form. Those aren’t numbers we pulled out of the air to look generous - they’re the numbers where a personal site, a community group or a one-person trade business is genuinely, permanently sorted and never has to think about it again.
Most contact forms get a handful of messages a month. If that’s you, you should never pay us anything. And beyond that it’s pay-as-you-go per 500 submissions, no subscription, no lock-in. If you have a quiet quarter, you pay us nothing for a quarter. That felt like the only honest way to price a thing that sits dormant most of the time.
Saying no is the actual engineering
Every single feature request that came in was reasonable. Every one. Form analytics, file uploads, a full CRM, autoresponders, A/B testing, a dashboard with graphs on it.
We said no to nearly all of it. What went in was the short list of things that make the core job work properly: webhooks to Slack, Discord and Telegram, custom redirects after submit, domain whitelisting, API access and a 90-day archive so you can go back and find the enquiry you accidentally deleted.
The hardest engineering in a small product isn’t the code. It’s the list of things you decided not to build, and holding that line when someone friendly and enthusiastic asks you to break it.
Doing this alongside the day job
Here’s the honest part, because I think this is the bit people skip when they tell these stories.
Product work is the first thing sacrificed when a client has a deadline. Always. There were months where Static Contact got zero minutes, because a client build needed all of us and that’s what pays the wages. There were evenings I sat down to work on it and got maybe forty minutes of useful thinking done before I was too fried to be any good to it.
What got it over the line wasn’t inspiration or a heroic weekend. It was small, consistent, unglamorous steps over a long period. An hour here. A bug fixed on a Tuesday night. The persistence to come back to a thing that nobody was asking for and nobody was paying for, again and again, until it was real.
The other thing I didn’t expect: building and running our own product has made me a considerably better consultant. When you build for a client, you feel the consequences of your decisions until the invoice is paid. When you build for yourself, you feel them for years. Every lazy shortcut, every “we’ll fix that later”, every bit of complexity you added because it was interesting rather than necessary - it all comes back and sits on your desk. That’s a hell of a teacher, and it’s changed how I advise people about their own builds.
Launched
Static Contact went live in November 2024, and it’s been quietly catching forms ever since. It runs this site’s contact form too, which feels about right.
If you’ve got a static site with a form problem, or you’re staring down that end-of-project conversation right now, go and have a look: staticcontact.com. The free tier is genuinely free and there’s no card required to find out if it works for you.
And if you’ve got a problem you’ve solved five different ways and you’re starting to suspect there’s a product hiding in it - I’d love to hear about it. That conversation is one of my favourites.

