I did this in the wrong order.
At least, that was my first thought.
I was building a small project that checks images and documents for privacy risks. The backend came first, then the API, then a frontend that finally made it feel like an actual service.
Somewhere along the way, I realized something.
I had built quite a lot before properly organizing the requirements and documentation.
Normally, I would expect the order to look more like this:
requirements → design → implementation → testing → documentation
Mine looked closer to this:
build → break something → fix it → build more → test it → finally organize everything
Not exactly textbook development.
But writing the documentation afterwards turned out to be more useful than I expected.
The README became a way to inspect the project
At first, I thought I was just writing down what I had already built.
Instead, I kept finding things that were unclear.
What does this API actually guarantee?
What configuration is required before running the project?
What happens when an external dependency is unavailable?
Which parts have actually been tested?
Would someone other than me know how to start this project?
These are simple questions.
They become much harder to ignore when you have to explain the project in plain English.
And that was probably the most useful part.
Documentation stopped being something I needed to finish after development.
It became another form of testing.
AI made building faster, but that created a different problem
I also used AI quite heavily while building.
ChatGPT, Claude, and coding tools made it much easier to move from an idea to working code.
That part was great.
But faster implementation also meant I could move past decisions without really stopping to organize them.
A configuration works, so I move on.
An endpoint returns the right response, so I move on.
Docker starts successfully, so I move on.
Then deployment comes.
Suddenly all the small things I skipped become visible again.
Environment variables.
Ports.
Database configuration.
Build commands.
Health checks.
Logs.
Security settings.
Things that looked like small details on localhost started feeling much more important once I tried to get the application outside my own machine.
That was the point where I started thinking less about:
“Does this code work?”
and more about:
“Is this actually ready to leave localhost?”
There is a bigger difference between those two questions than I expected.
A working MVP is not the same as a shippable MVP
I used to think of an MVP mainly in terms of features.
If the core function works, the MVP works.
I still think that is partly true.
But there is another stage after that.
The application has to survive being run somewhere other than your laptop.
Someone needs to know how to configure it.
You need to know when it has failed.
Secrets should not be sitting in the repository.
The build should be reproducible.
The production environment should not depend on something you happened to configure manually three days ago and already forgot about.
None of these things are particularly exciting.
They are also exactly the things I kept running into.
So I started writing them down.
Not as another tutorial.
Just as a checklist I wanted for myself the next time I reached this stage.
That checklist became its own project
Eventually those notes turned into Ship Your Spring Boot MVP.
I made a smaller Free Edition public on GitHub:
👉 Ship Your Spring Boot MVP — Free Edition
It is a practical pre-launch checklist for Spring Boot MVPs.
The idea is simple:
before calling an MVP ready, go through the things that are easy to miss when most of your attention has been on making the feature work.
I also ended up expanding those notes into a more detailed Full Edition with more checks, verification steps, deployment notes, and the things I wish I had organized earlier.
I'm still preparing that version, so for now the Free Edition is the one I'm sharing publicly.
I did not originally plan to make a product out of it.
It came from repeatedly asking myself the same question while building:
“What am I forgetting before I ship this?”
I still don't think building first is the correct order
I would not turn this into advice like:
“Forget requirements. Just start coding.”
That would be the wrong lesson.
If anything, doing it backwards showed me why the earlier steps exist.
But there was something valuable about documenting a project after I had actually struggled with it.
The checklist was no longer theoretical.
Every item reminded me of something I had needed, forgotten, broken, or had to go back and check.
Maybe next time my process will be a little cleaner.
Probably not perfectly clean.
And that's fine.
I'm still learning by making things.
I keep more notes about development, AI tools, deployment, and the things that break along the way on the Nocklock blog.
You can also see the projects I'm building on GitHub.
Top comments (1)
"Does this code work?" vs "Is this actually ready to leave localhost?" — that's a genuinely useful reframing. Most MVP checklists stop at feature completeness and skip exactly the things you're describing: environment variables, secrets management, health checks, reproducible builds.
The part about AI making it easier to move past decisions without stopping to organize them is real. You can get to working code faster, but "working on my machine" and "shippable" are still two very different bars. If anything, faster iteration makes the gap more visible at deployment time.
Documentation-as-testing is something more teams should internalize. The moment you try to explain what an API actually guarantees in plain English, you find out whether you actually decided that — or just hoped the code implied it.
Appreciate you turning the checklist into something shareable rather than leaving it as personal notes. That's usually where the useful stuff stays buried.