A good app spec names one user, one job, the screens, the data, and what is out. Write it in an hour and you save weeks of build drift.
By Brian, founder-engineer at Lab Twelve.
A good app spec is a short document that any engineer can read once and start building from without a meeting. It names the user, the job, the screens, the data, the integrations, and the things you are deliberately not building. That is it. Most specs fail not because they are too short but because they describe a feeling instead of a system. "A platform for creators" is a feeling. "A creator uploads a video, sets a price, and gets paid when someone unlocks it" is a spec.
I read specs for a living. The ones that turn into clean fixed-price builds share a shape, and you can copy that shape in about an hour. This post is the shape.
Founders often treat the spec as a place to dump everything they might want someday. That is the wrong instinct. A spec is the place where you make decisions and write them down so nobody has to guess later. Every line should close a question, not open one.
Compare these two lines from real briefs I have seen:
The first line is four more meetings. The second line is buildable today. It also tells the engineer what is out, which is where most of the cost hides. Specs that only list what is in always cost more than expected, because the gaps get filled with assumptions, and assumptions get filled with the most expensive interpretation.
Before you list a single feature, write one sentence: who is this for, and what are they trying to get done. Not three personas. One. If your product genuinely serves a buyer and a seller, pick the side that has to show up first and spec that side. The other side is v2 until the first side has someone using it.
The format that works:
"When [situation], [this user] wants to [do this thing], so they can [get this outcome]."
Bad: "Small businesses need a better way to handle invoices." Good: "When a freelancer finishes a project, they want to send a branded invoice and get paid by card, so they stop chasing bank transfers over email."
If you cannot write the good version, you do not have a spec problem. You have a discovery problem, and you should go talk to five of these users before you write anything else. We say this constantly because it is the single most common reason a build goes sideways. See how to scope an MVP for the checklist version of this.
A screen is a thing the user looks at and acts on. Listing screens is the fastest way to find out how big your idea really is, because every screen is real work: layout, states, validation, empty case, error case, loading case.
Write them as a flat list with one line each:
Four screens is a real product. Six is a full one. If your list hits twelve before you have a paying user, you are describing a company, not a first version. That is the moment to cut, not the moment to raise a round to afford the cut. Feature count discipline is covered in how to scope an MVP, and the cost of each extra screen is in the 2026 cost guide.
The screen list is the cheapest honesty in the whole process. It tells you the size of your idea before you spend a dollar finding out.
You do not need diagramming software. You need a list of the things your app stores and the important fields on each. This is what makes a spec actually buildable, because data is where ambiguity becomes bugs.
| Entity | Key fields | |--------|------------| | User | email, name, created_at | | Invoice | user_id, client_name, amount, status, due_date | | LineItem | invoice_id, description, quantity, unit_price |
Then answer the relationship questions, because these are where builds quietly diverge from what you imagined:
If you cannot fill this table, you are still in discovery. That is fine. Do not lock a fixed price on a data model you cannot draw.
Every integration is real work: credentials, test mode, error handling, often webhooks. The rule that keeps specs honest is simple. If you do not have an account and an API key for it today, your first version probably should not depend on it.
| Need | First version | Later | |------|---------------|-------| | Payments | Stripe Checkout | Subscriptions, invoicing | | Email | Resend transactional | Marketing sequences | | Auth | Email magic link | Google OAuth, SSO | | Files | S3 or R2 upload | Image transforms, CDN |
"Connect to Salesforce" in a first-version spec is a yellow flag. It is usually defensible and almost always better as a manual CSV export until someone is actually paying. Put it in the out list and revisit it when a customer asks.
I will say this plainly: the section of the spec that saves you the most money is the list of things you are not building. Write it explicitly.
EXPLICITLY OUT OF V1
- No native mobile apps
- No multi-tenant or white-label
- No team accounts or roles beyond owner
- No public API
- No AI features
- No admin analytics dashboard (use a SQL query for now)
Every item here is an argument you will not have at week three. When someone says "I assumed analytics was included," the out list is the document that ends the conversation in thirty seconds instead of a tense afternoon. A spec with an empty out list is not a spec. It is a wish with formatting. This is the same discipline that makes fixed-price development actually work.
The last section is acceptance: how you will both agree it is finished. Vague done is how projects drag.
Write it as things a test user can do on a real URL:
If you can check those boxes on a live deploy, it is done. If you cannot, it is not, regardless of how good the demo looked. This is the difference between a prototype and a product, and it is worth being strict about.
You do not have to write all of this perfectly on your own. The point of writing a draft is to arrive with decisions instead of vibes. When you run your idea through /start, the scope chat asks for exactly these pieces in order: user and job, screens, data, integrations, and what is out. It fills structured fields, scores how complete the picture is, and only then maps you to a fixed price from the published tiers. Models extract the scope. A deterministic engine sets the number. That is the whole reason the quote you see matches the invoice you pay.
So the honest workflow is: spend an hour on the draft above, then let the chat pressure-test it. The draft makes the chat fast. The chat makes the draft buildable. Both make the price real.
A good spec feels almost embarrassingly small when you finish it. That is the feature, not the bug. The embarrassing thing is not a tight first version. The embarrassing thing is paying to build twelve screens nobody asked for because the spec was a paragraph of adjectives.
Get a fixed quote in one conversation.
Describe your build and get a fixed quote before you pay.
Start an AI scope
Most non-technical founders chase a CTO when they actually need v1 in production. Here is how to tell the two problems apart before you give away equity.

A native mobile app costs more, ships slower, and is harder to change than a responsive web app. For most first versions, the web is the correct first bet.

An internal tool serves your team and ships fast. A SaaS product serves strangers and carries ten times the surface. Build the one your evidence supports.
Ready to scope your app?
Describe your build and get a fixed quote before you pay.
Start an AI scope