Skip to content
← All articles

AI coding · Shipping

Why your AI-built app is stuck at 90%

4 min read

You described the app to your AI assistant on Friday night. By Sunday it had screens, a database and a few features that worked on your laptop. Three weeks later, it still isn’t in front of a single paying customer.

This is the most common story in AI-assisted coding, and it isn’t about the features. The features were the easy part. What stops the launch is everything underneath them: the work nobody demos and every real product needs.

The last 10% is most of the work

An AI assistant is excellent at the code you can see. It is much weaker at the code that only matters on the day something goes wrong. Here is what usually blocks the launch.

Sign-in that holds up

A sign-in screen takes minutes. Sign-in that survives real users takes much longer: email verification, password resets, social logins, sessions that expire, bot sign-ups, and teams where one person invites another. Building it yourself means owning every security mistake in it.

Payments that change what people can do

Stripe Checkout is easy to open. The hard part is what happens after: the payment arrives as a webhook, sometimes twice, sometimes late, sometimes out of order. A renewal fails. A customer disputes a charge. If your app grants access from the “thank you” page, anyone who finds that address gets the paid plan for free.

One customer never seeing another’s data

The moment two companies use your app, every query must stay inside one workspace. One forgotten filter in one new feature, and a customer sees someone else’s projects. An AI assistant adding features quickly is exactly how that filter gets forgotten.

Getting it online, and keeping it there

HTTPS certificates, database migrations that run before the new version starts, backups that happen every night without you, logs you can read, alerts when something breaks, rate limits so one script can’t take you down. None of it shows on a screenshot. All of it matters the first week you have customers.

Code that drifts with every prompt

Each prompt is a new conversation. The assistant forgets the conventions it followed yesterday, reinvents a helper that already exists, and quietly breaks something two folders away. After a few weeks, nobody, human or AI, can change the code with confidence.

What actually gets you to launch

The fix is not a better prompt. It is giving the assistant two things it can’t create on its own: a foundation that is already finished, and rules it can’t skip.

Start from a finished foundation

Sign-in, workspaces, roles, billing and deployment are not what makes your product different. Start from a codebase where they are already built and tested, and spend your prompts on the features only you can design. The assistant then extends something solid instead of improvising the plumbing.

Make the rules checkable, not just written

A long instructions file helps, but assistants forget written rules. Tools don’t. Lint rules that explain each error and what to write instead, a type check, unit and integration tests, and one command that says whether a change is done. When the assistant must run that command and fix what it reports before it says “finished”, the quality stops depending on its memory.

Give it examples to copy

Assistants follow an example more reliably than a description. One complete feature, from the database table to the page, with its permissions, translations and tests, becomes the pattern every new feature copies.

A checklist before your first paying customer

  • Sign-up is protected against bots, and a signed-out request to your API is refused.
  • Every query that reads customer data is limited to one workspace, and a test proves it.
  • Access to paid plans changes only when a signed payment webhook says so.
  • Webhooks are stored first and processed in the background, safely if they arrive twice.
  • Migrations run on every deploy, before the new version starts.
  • The database is backed up every night, and you have tried restoring a backup.
  • Sensitive actions are rate limited, and server errors reach you as alerts.
  • One command checks lint, types and tests, and your assistant runs it before every “done”.

Where Neatship fits

We built Neatship because we kept rebuilding this list for every new product. It is a starter with all of it already done: sign-in and workspaces with Clerk, Stripe subscriptions driven by webhooks, English and French, a design system, and a one-server Docker deployment with HTTPS, migrations, nightly backups, rate limits and error alerts.

It also comes with the rules your assistant follows: a rulebook it reads, 17 custom lint rules that explain themselves, and yarn verify, the one command that says a change is done. In Claude Code, hooks lint every file the assistant edits and make it run that command before it ends its turn.

You can try the result in the live demo, in one click, without creating an account.