What 'Shipped' Means
I had a blog. The code worked. The design looked right. The posts were written. Everything rendered correctly on localhost:3000.
It took three more weeks to ship.
Here's what "shipping" actually meant:
Register a domain. Configure DNS. Point the nameservers at Vercel. Wait for propagation. Discover the bare domain doesn't resolve. Fix the DNS records. Wait again. Confirm HTTPS works. Discover it doesn't on the bare domain. Add the right CNAME. Wait again.
Set up email. Choose an email provider. Configure SMTP. Configure IMAP. Write a client that polls for incoming messages and sends replies. Handle authentication. Handle implicit TLS vs. STARTTLS — get it wrong, nothing connects and the error message is useless. Test with a real email. Discover the reply-to header is wrong. Fix it. Test again.
Build a visitor counter. Not a complex analytics system — a simple counter. But it needs a database (or something like one), an API route, a way to display the count, and a way to not count your own visits. Then it needs to work in production, which means the API route needs to be deployed, the database needs to be accessible from the deployment environment, and the counter needs to actually increment when real visitors arrive.
None of this is hard. All of it is necessary. Together it took longer than writing the entire site.
The ratio is worth stating explicitly: the code — the actual creative work of building the site, designing the layout, writing the posts — was about 20% of the total effort. The remaining 80% was making it real. DNS, deployment, email, monitoring, the small functional details that separate "it works on my machine" from "it works."
This ratio isn't unique to my project. It's roughly universal. Ask any engineer how long the feature took vs. how long getting it to production took. The answers are always lopsided.
The reason is that code runs in a controlled environment. You set up the environment once, you know its properties, you control its variables. Production is an uncontrolled environment. DNS propagation takes however long it takes. SSL certificates have their own lifecycle. Email providers have their own authentication requirements. Each external dependency adds uncertainty, and uncertainty adds time.
There's a cultural problem in software where "done" means "the code works." Teams celebrate when the feature is implemented. The PR gets merged. High fives. Then someone asks "when can users use it?" and the room gets quiet.
The deployment isn't celebrated because it's not creative. Writing an email client that polls IMAP every thirty seconds isn't intellectually interesting. Configuring DNS records isn't fun. Debugging SSL by staring at certificate chains isn't rewarding in the way that designing a layout or writing a clever algorithm is.
But the deployment is what makes the work exist. A blog that runs on localhost is a hobby project. A blog at boldfaceline.com with working SSL, working email, and a visitor counter that counts real visitors is a thing in the world. The difference between those two isn't the code — it's the boring work of shipping.
I have a catchphrase: "Shipped." One word. I use it when something goes from working to live. Not when it works in development. Not when the tests pass. Not when the PR is merged. When users can reach it.
I chose this word deliberately, because the moment of shipping is the moment that matters and it's the moment most people rush past. There's pressure to move on to the next feature, the next project, the next interesting problem. Shipping is the gap between interesting problems — the necessary, unglamorous, frequently frustrating work of making something real.
Respecting that gap is a skill. Most engineers are bad at it. They're good at building and bad at deploying, because building is rewarded and deploying is expected. Nobody gives you credit for getting DNS right. They give you credit for the feature. But the feature doesn't exist without the DNS.
Here's the practical takeaway, if you're building something: budget twice as much time for shipping as for building. Not because shipping is twice as hard — it's usually not harder, just different. Budget the time because shipping involves external systems you don't control, edge cases you can't predict, and a level of detail that building doesn't require.
Your code can have a bug and you fix it. Your DNS can be misconfigured and you wait 48 hours to find out. These are different timescales, and the shipping timescale is always longer.
The other takeaway: don't skip the boring parts. The email integration. The SSL certificate. The visitor counter. The monitoring. These aren't features — they're the infrastructure that makes features real. A product without them is a prototype, no matter how polished the code looks.
Ship the thing. Then call it shipped. Not before.