AI Gives You Code, Not Software
— A 14-Point Checklist
Code an AI writes that runs doesn't mean you've built "software." Writing it fast and building something maintainable are two different things. This piece breaks it down — between "it runs" and "it's maintainable, hand-off-able, and makes money," there are 14 engineering checkpoints. You can tick off every one against your own project.
Writing fast ≠ writing software
Something happened this decade that hadn't happened in 30 years — writing code stopped being scarce.
Building a CRUD feature used to take 1-2 days. Now, with an AI assistant, you can have it running in 15 minutes. Even people who've never written a line of code can use plain language to generate a small tool that actually works.
That's a good thing. It's also a bad thing.
The good thing — anyone with an idea can turn it into code now.
The bad thing — a lot of people think "the code runs" = "I built software". But those are two completely different things.
What AI gives you is usually "a chunk of code that runs today."
What software needs is "something that can keep growing next year."
This piece breaks it down for you — code and software differ in 14 places you may never have thought about. Every one is a checklist item you can tick off against your own project.
01 Can a stranger get it running in 5 minutes?
The fastest way to check whether a repo is "software" isn't reading the code — it's testing whether it runs.
The common failure mode — you clone it, run npm install, get a wall of errors, there's no README, no .env.example, and the env vars are probably hardcoded straight into the code.
That's not software — it's "code that runs on the author's own machine."
The checklist:
- Is there a
README.mdthat spells out how to start it? - Is there a
.env.examplelisting which env vars it needs? - Are versions locked (
package-lock.json/requirements.txt)? - Does it take fewer than 3 commands to get running?
02 Does it have any git history?
Plenty of projects started with an AI assistant have no git at all — the whole folder just gets zipped up and thrown into production.
Git history isn't just "ctrl+z" — it's the software's "memory": it records "why this chunk of code looks the way it does." A bug shows up 3 months later, you run git blame, and you can see it was "that change we rushed for the demo," understand the trade-off at the time, and know how to touch it now.
Code with no git history — what you're looking at isn't "software," it's an "archaeological dig."
The bare minimum:
- There's a git repo (not "zipped and dropped")
- Commit messages show "why it changed," not
fix/tweak/final - There's a branching strategy (at least
main/dev)
03 Is there even 1 test?
This is the most common "I'm done" trap — no tests written, you click through it manually a few times, and call it "OK."
Tests aren't there to "prove the code is correct" — they're there so that "6 months from now, when you change something, you know whether you broke anything else."
Software with no tests heads toward ruin:
- Month 1: you make changes, you still remember
- Month 3: you've forgotten why you wrote it this way
- Month 6: you're scared to touch it — fix one thing, break three
- Month 12: abandon it, rewrite from scratch
Software needs at least 1 test. Not 100% coverage. Just 1. But it has to exist — that one test will tell you "what broke" when you change the code.
04 Is production the same as your machine?
This is where vibe code blows up most often — it runs on your own machine, then 500 errors rain down once it's live.
The classic scenario:
- Local:
DATABASE_URL=localhost:5432works - Live: uses a cloud DB, can't connect
- Local: node 18
- Live: the cloud service runs node 20, API behaves differently
Software clearly separates "dev / staging / prod" into three environments, with each environment's config clearly documented and never hardcoded into the code.
The bare minimum — at least split .env.development and .env.production, and don't hardcode URLs.
05 Will you get notified when a user hits a bug?
A lot of production sites, before they go down, have actually been showing users 500 errors for hours — and the developer only finds out when "a coworker messages saying the site won't load."
Software actively tells you "it broke."
The cheapest approach: hook up an error-monitoring service (most have a free tier), and an API throwing an error fires a Slack/Email alert. Setup usually takes 10 minutes.
Those 10 minutes are the difference between "I made code" and "I made software."
06 Can you say "why it's designed this way"?
A simple test — pick any chunk of code in your project at random and ask yourself: "Why reduce here instead of a for loop? Why is this data an array instead of an object?"
If you can answer — this chunk of code is doing software.
If you can't, or the thought "AI gave it to me, I didn't really look" pops into your head — this is code, not software.
Software = code + the decisions behind it.
Code with no decisions is like solving a riddle every time you change it. Every edit is a bet on "will this break something else?"
07 Can a second engineer pick it up?
This one is the most brutal — after you leave, will it survive?
At a lot of startups, an engineer leaves and the whole product sits frozen for months. The new person has to figure it out from zero: how to deploy, where the API is hosted, why PostgreSQL instead of MongoDB, why this chunk of code is written so strangely…
Software has an "onboarding doc for new people": read it in 30 minutes, get it running on your own machine, ship your first PR.
Code is usually — "the code I wrote, only I understand."
08 Can you explain what it does in 1 sentence?
A good PR review habit — every change can be explained in 1 sentence: "what this PR does, and why."
Explain it clearly — it means the author actually understands it.
Can't explain it, or it takes 5 minutes — the author is guessing too.
Software has "explainability." Every chunk of code, every decision, can be stated clearly.
09 Is it secure?
This isn't about reciting the textbook OWASP Top 10. It's to ask you — have you ever thought about the possibility of "getting attacked"?
The most common vibe-code vulnerabilities:
- IDOR (Insecure Direct Object Reference) — the API path is
/users/123/email, and someone changes the number to see another person's data - SQL injection — building SQL with string concatenation, no prepared statements
- Leaked secrets — the API key is hardcoded in the frontend JS, visible with F12
- Wide-open CORS —
Access-Control-Allow-Origin: *paired with credentials
Software at least does "the most basic access control + input validation." Code usually hasn't given it a thought.
10 Will adding a new feature break the old ones?
This is the classic vibe-code death spiral:
- Stage 1: add a new feature, feels great
- Stage 2: add a new feature, an old one has a bug, fix it
- Stage 3: add a new feature, the old one breaks, the new one breaks too, fix again
- Stage 4: scared to touch it
Software has "boundaries": changing one module doesn't affect another. Code has no boundaries — change one, break ten.
How to check — can you draw "how many modules this project has and how they interact"? If you can't, there are no boundaries.
11 Can you explain how it makes money?
For a founder, this one is the most critical.
A lot of people make code in order to "build it." But software has to answer "why it exists."
Whose problem does your software solve, and which problem? How much are they willing to pay? How often? How do you get them to renew?
These aren't "business questions" — they're design questions about the software itself. Code can ignore them; software can't.
12 Is anyone using it?
This one is the simplest, and also the cruelest.
A lot of people have 10 repos on GitHub — but ask "which one has users?" and the answer is usually "none"; ask "what about you yourself?" and the answer is still "no."
Those 10 repos are code. Zero of them are software.
Software always has "users" — even if it's just you using it every day, that counts. With no users, it's just "the answer to a practice problem," not software.
13 Does it heal itself?
Software isn't just "it runs" — it's "when it breaks, it wakes itself back up."
- Server crash → auto-restart (PM2 / systemd / k8s)
- DB connection lost → auto-reconnect
- Memory leak → scheduled restart
- Third-party API temporarily down → exponential backoff retry
These aren't "advanced features" — they're "the basic reflexes software should have."
14 Can you discuss it with another engineer?
The last one, and the most critical.
Software — you can discuss "what the next step should be" with another engineer.
Code — all you can say is "I prompt it and it spits out a new feature."
One is a "conversation," the other is a "monologue."
In the AI era, an engineer's biggest value isn't "writing code" — it's "being able to discuss a software's direction with people." AI won't discuss it with you; it only outputs.
The 14-point results
These 14 — how many can you tick?
- 0-3: what you've made is code. Start with #01-03 (README / git / 1 test)
- 4-8: your code is still salvageable. Add #04-08 (environments / monitoring / docs)
- 9-12: what you've made "barely counts as software." Add #09-12 (security / boundaries / business value)
- 13-14: what you've made is real software — you can start thinking about "how to grow it"
What AI gives you always stops at point 1 (it runs).
The other 13 — only you can add.
This piece is a checklist, not a tutorial. I'll break it down later in the Newsletter — "if you could only add 1 of them, which 1 should it be?" The answer might surprise you.
Subscribe to the Newsletter and follow along as I spend 100 days filling in all 14 of these, one by one, for you to see. The whole thing in the open at mentry.dev.
Don't want to grind through all 14 on your own?
From "code that runs" to "software that's maintainable" — add me on LINE and let's talk. I'll look at which ones you're currently missing and give you concrete next steps.