How to Deploy an App You Built With AI

Four things break when an AI-built app goes live: environment variables, the database, the domain, and the API call. How to spot and fix each, plus a pre-launch checklist.

Steve Jefferson
Steve Jefferson
Developer Advocate
2 August 20261 min read

Your app works. You click through it, everything responds, the data saves. Then you deploy it and the login breaks, the AI feature returns an error nobody can read, and the custom domain shows a certificate warning. Nothing is wrong with your app. Deployment is a different environment with different rules, and four specific things account for almost every failure.

This walks through those four, in the order they usually bite, with the checks that tell you which one you are looking at.

Before you deploy: the ten-minute audit

Three questions, asked of your builder or of your code, save most of the pain.

Where are your secrets? Every API key, database password, and access token. If any of them appear in files that get sent to the browser, you have a problem that deployment will expose rather than cause. Ask your builder directly: "which environment variables are exposed to the client, and is any API key among them?" Frameworks generally mark browser-visible variables with a prefix, and anything sensitive must not carry it.

What does the app assume about its own address? Apps built locally often have a localhost address written into them somewhere: a redirect URL, an API base path, an allowed origin. Every one of those needs to become the real domain.

Does the database exist yet in production? Your local database has tables because you created them while building. A fresh production database has nothing. Something has to create that structure, and finding out at deploy time is unpleasant.

Failure one: environment variables

The most common by a wide margin, and it produces the least helpful error messages. A missing variable usually surfaces as "undefined is not a function", a blank page, or a 500 with no detail, none of which point at the cause.

What to do:

  1. List every variable your app reads. Search the code for the pattern your framework uses to read environment variables, and collect the names.

  2. Set each one in the host's environment settings, not in a file you upload. Files with secrets in them should never reach the server.

  3. Check the client and server split. Variables meant for the browser need the framework's public prefix. Variables holding secrets must not have it. Getting this backwards either breaks the app or leaks the key, and the second failure is silent.

  4. Redeploy after changing them. Nearly every platform bakes environment variables in at build time, so editing them without a rebuild changes nothing and you will spend twenty minutes convinced the platform is broken.

Diagnosis tip: if the app works locally and fails immediately in production with an unhelpful error, this is the first thing to check, every time.

Failure two: the database

Your local database has structure and probably some test data. Production has an empty database, or none at all.

The structure has to get there through a migration, which is a file describing the tables and columns. Most AI builders and frameworks generate these, and the step people skip is running them against production. If your platform has a deploy command or a migration button, that is what it is for.

Two further traps:

Connection strings differ. Production uses a different host, different credentials, and usually requires SSL where local did not. This lives in an environment variable, which loops back to failure one.

Test data does not travel. The categories, settings rows, or admin user you created by hand while building do not exist in production. If your app assumes at least one row exists somewhere, it will break on an empty table. Either seed that data deliberately or make the app handle empty gracefully, which is better anyway.

If you are not sure whether your app even has a database it needs to worry about, do I need a backend for my app covers how to tell.

Failure three: the domain and HTTPS

Deploying gives you a working URL on the platform's domain. Pointing your own domain at it is a separate job with its own failure modes.

The mechanics are simple. In your domain registrar's DNS settings, add the records the hosting platform tells you to add, usually an A record for the root domain and a CNAME for the www subdomain. Then wait. DNS propagation is genuinely slow, commonly a few minutes and occasionally a few hours, and there is nothing to fix during the wait.

Where it goes wrong:

  • Certificate warnings. Almost always because the certificate is issued after DNS resolves. If you added the records five minutes ago, wait. If it has been a day, the records are wrong.

  • Root domain versus www. Pick one as canonical and redirect the other. Serving both independently splits your traffic and, if you care about search, your ranking signals.

  • Old DNS records left in place. A leftover A record from a previous host will fight the new one, and the result is a site that loads intermittently depending on which record a resolver picked up. Delete the old ones.

  • The app still thinks it lives somewhere else. Redirect URLs, allowed origins, and any hardcoded base URL now need the real domain. Auth providers are the usual casualty: the login flow completes and then bounces the user to localhost.

Failure four: keys, origins, and the AI call

If your app calls an AI model, this is where it breaks, and it breaks in a way that looks like the model is down.

The key must be server-side. If the browser makes the call, the key is in the browser and anyone can take it. The fix is a small server-side function that receives the request, adds the key, and forwards it. This is not optional and it is not a scale concern, it is the difference between having an API bill and having someone else's API bill.

CORS. Your browser will refuse requests to a server that has not explicitly allowed your domain. The error mentions cross-origin and is fairly clear once you have seen it once. Fix it by adding your production domain to the allowed origins on whatever is receiving the request, and remember that the deploy preview URLs many platforms generate are different origins again. MDN's CORS guide is the reference worth keeping open.

Timeouts. Serverless functions have execution limits, often ten to sixty seconds by default. A model generating a long response can exceed that, and the failure looks like a hang followed by a generic error. Either stream the response, raise the limit if your platform allows it, or move the work to a background job and poll for the result.

Rate limits and cost. Local testing is a handful of requests. Production is however many users you have, in parallel. Put a per-user limit in before launch, not after the bill arrives. This is a fifteen-minute job and it has saved a lot of people a lot of money.

A deployment checklist

Run this once before you send anyone the link.

  1. All environment variables set on the host, correct public and private split, redeployed after changes.

  2. Migrations run against the production database, seed data present if the app needs it.

  3. Custom domain resolving, HTTPS valid, one canonical version with the other redirecting.

  4. All redirect URLs, allowed origins, and auth callback URLs updated to the production domain.

  5. AI and other paid API calls happening server-side, key not present anywhere in the browser bundle.

  6. Rate limiting on anything that costs money per request.

  7. Error logging enabled somewhere you will actually look.

  8. A real end-to-end pass on the production URL: sign up as a new user, do the main thing the app is for, sign out, sign back in.

That last one catches more than the other seven combined, because it is the only step that exercises the whole system as a stranger.

After it is live

Two habits worth forming early.

Watch the logs for the first day. Not obsessively, but the first real users will hit things you did not, and the errors are far easier to fix while you still remember how the code works.

Deploy small changes often rather than large ones rarely. A broken deploy with one change in it is a two-minute diagnosis. A broken deploy with thirty changes is an afternoon. This matters more with AI-generated code than with handwritten code, because you have less of the system in your head to begin with, which is part of why the review discipline in choosing AI coding tools is worth taking seriously.

If deployment is where your project stalls, that is normal, and it is the point where the gap between an app builder and a hand-rolled stack narrows sharply. Building an app with AI covers the earlier stages, and building an internal tool covers the case where the audience is your own team and the domain question mostly disappears.

Frequently asked questions

Do I need to deploy at all if my app builder hosts it?

No, and that is a legitimate reason to stay on a builder's hosting for a first version. You would move when you need a custom domain the builder does not support, specific infrastructure, or an exit path from the platform. Check whether you can export the code before you depend on it.

Why does my app work locally but break in production?

Ninety percent of the time it is one of four things: a missing environment variable, a database that has not been migrated, a hardcoded localhost URL, or a CORS rule that does not include your production domain. Work through those in that order.

How much does hosting a small app cost?

Free tiers on the major platforms comfortably handle a project with early users, and the first paid tier is typically in the range of a few dollars to twenty dollars a month. The costs that actually surprise people are AI API calls and database egress, not hosting.

What is a migration and do I need one?

A migration is a file that describes a change to your database structure, so the same change can be applied to another database. You need them the moment you have more than one database, which happens the moment you deploy. Most frameworks and builders generate them for you.

Should I use a staging environment?

Once you have real users, yes. Before that it is overhead. A middle path that works well is to use your platform's preview deployments, which give every change its own temporary URL, and remember to add those URLs to your allowed origins.

If you eventually need to move the project off the builder entirely rather than just deploy it, how to export an app from an AI app builder walks through that separate process.

How did this land?

About the author

Steve Jefferson
Steve Jefferson

Developer Advocate

Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.

Share

Get the next post in your inbox

One email a month. Product updates, engineering posts, and the best of Built with Swarmz.

I agree to receive emails about AI building tips and Swarmz product news. Unsubscribe any time.