Deploy & hosting
Monorepo apps, provisioning add-ons, domains, deployments, and debugging with your AI assistant.
Production hosting on LaunchWithCursor covers GitHub access, deployable apps, optional services (database, Redis, storage, email), environment variables, domains, and releases — one platform instead of juggling Render + Supabase + SendGrid + Cloudflare separately.
Why this matters: Each extra vendor means another login, another bill, and another place settings can drift. LaunchWithCursor keeps code, infra, and secrets in one place.
Start with the extension
Deploy instructions are automatically copied into your repo when you install the LaunchWithCursor extension — under .launchwithcursor/pack/LAUNCHWITHCURSOR/.
What to do:
- Install the LaunchWithCursor extension in VS Code or Cursor — one-time setup. See Install & sign in.
- Open your project and sign in — the starter pack copies to your repo automatically.
- Use the prompts on Sample prompts whenever you plan or build — they tell your AI coding assistant that you intend to deploy on LaunchWithCursor so it structures the project correctly and follows the pack the extension installed.
Use this web guide for browsing. On the dashboard, open Deploy → Checklist for a step-by-step pre-flight tied to your project.
Already have an older codebase? Use the Existing project → LaunchWithCursor prompt on Sample prompts so your assistant first decides whether the repo can move comfortably before planning changes.
GitHub access
Connect GitHub so each deploy can clone your repository. New to Git? See Git & GitHub.
Deploy clones your repository on every build using the GitHub account of whoever triggers the deploy. You do not need to own the repository — collaborator access with read permission is enough.
Connect GitHub under Settings → Connections (or sign in with GitHub). On Deploy → Overview, pick a repository or paste a URL. For private org repos, your GitHub organization may need to approve the LaunchWithCursor OAuth app.
Transferred a project or repo? See Transfer ownership.
Plan with Sample prompts
When your AI coding assistant creates MVP-SPEC or build phase plans, use the copy-ready prompts on Sample prompts. They reference the LaunchWithCursor pack in your repo so plans include the right structure for deploy, env vars, and add-ons.
You do not need to memorize internal config file names — the extension and those prompts communicate deploy rules to your assistant for you.
What is a deployment?
A deployment is an attempt to make what you built available to use on the internet (or on a private staging URL).
- Production — real users or customers use the live version.
- Staging — you and testers try changes on a separate URL before promoting to production.
Each time you click deploy for an app (see below), LaunchWithCursor builds from your Git branch, applies your env vars, and starts (or updates) that app on the platform. A failed deployment means the app never reached a healthy running state — fix the build or config and deploy again.
Monorepo structure (why AI loves it)
A monorepo means one Git repository (repo) containing several related apps in subfolders instead of many separate repos.
This is a common layout LaunchWithCursor and AI coding assistants work well with for greenfield MVPs:
| Folder | Typical role |
|---|---|
apps/web | Public website or customer app (often Next.js) |
apps/admin | Internal dashboard for you or staff (optional) |
apps/api | Backend API, auth, payments, webhooks (often NestJS) |
packages/* | Shared code both frontends and API reuse (optional) |
Other layouts are fine — single Laravel/Django apps, static sites, Bun, Java, Go, etc. See the Deploy setup guides and stack recipes. Your assistant configures build/start in the repo; you deploy from the dashboard.
PWA or native: Your MVP-SPEC may call for a Progressive Web App (installable from the browser) or a future native wrapper. Usually the website service covers the customer-facing experience; your assistant reads MVP-SPEC.md and the pack's PWA skills when that applies.
Why this matters: One repo means one place for your AI assistant to read specs, one push updates everything, and one Deploy checklist reflects the whole product.
Frameworks & databases
Greenfield favourites (best docs):
- Next.js + TypeScript for web/admin
- NestJS + TypeScript for APIs
- Postgres or MySQL — pick when you provision Deploy → Database (match Prisma/ORM to the engine)
Also deployable today: Vite/SPA, Express, Laravel, Django/Flask/FastAPI, static HTML, Bun, PHP, Java, Go — via Nixpacks or optional BYO Dockerfile.
Your assistant configures build and start commands in the repo; you deploy each app from the dashboard.
Deploying each app
On Deploy → Overview you will see one row per app (api, web, admin, etc.):
- Connect GitHub and choose the branch (staging vs production — see Git & GitHub).
- Complete Deploy → Checklist (env vars, domains, add-ons).
- Deploy api first on a fresh project if your product uses a database — wait until it succeeds before deploying
weboradmin. - Open the live URL from the overview and smoke-test in the browser.
Pick the Git branch on Overview — each build clones that branch.
Services you can provision
Besides deployable apps, LaunchWithCursor offers optional services (add-ons) your apps connect to. The extension and your repo tell the platform what you need; Deploy → Checklist shows what is still missing before you should go live.
| Service | When you need it |
|---|---|
| Database (Postgres or MySQL) | Users log in, you save orders, posts, profiles, or any data that must persist |
| Redis | Background jobs (emails, image processing), caching, session storage across restarts, or real-time features (chat, live updates, signalling) via Pub/Sub |
| R2 storage | User uploads, images, PDFs, or any files stored in the cloud |
| Magic links, receipts, password resets, or other transactional messages | |
| Domains (org-level) | Branded URLs like app.yourbrand.com — optional; a free platform URL is assigned on deploy |
Skip anything your MVP does not use — a static marketing site may need none of these.
Deploy → Checklist is your pre-flight list. It updates from your extension scan and repository so you know which services to provision before clicking deploy.
Bring existing database data
If you already have customer or product data in a local or legacy database, you do not need a public database URL just to move it into LaunchWithCursor.
After you provision Deploy → Database, open Deploy → Database → Import / Export on the hosted app:
- Download full backup first if the hosted database already contains data
- Upload your existing dump file
- Watch Recent import jobs
- Verify tables and rows under Deploy → Database → Manage data
Supported uploads:
- Postgres:
.dump,.sql,.sql.gz - MySQL:
.sql,.sql.gz
Before uploading, choose how the backup is applied:
- Replace current data — clears the hosted database first, then restores your dump. Best for full-site migrations and for retrying a failed import.
- Merge (keep existing data) — keeps every row already in the hosted database and adds only rows from your backup that are not there yet. Rows whose primary or unique keys already exist are skipped instead of duplicated, so the same backup can be re-imported safely. Rows that would break a foreign key are listed under View details rather than failing the whole import.
- Import on top (no de-duplication) — keeps existing data and applies the backup as-is. A row whose key already exists fails the import, so use it only when you know the data does not overlap.
Tip: to top up a live database from an older backup without losing current rows or creating duplicates, use Merge. It also advances your auto-increment counters, so new records keep working after the import.
If your repo owns the schema with migrations, usually deploy the DB-owning service (often api) first so the hosted database is provisioned and ready before import.
Why this matters: Founders should not have to learn
psql,pg_restore, SSH, or internal hostnames just to bring existing data into the platform.
Runtime OS packages (ffmpeg and similar)
If your API or worker needs system binaries (e.g. ffmpeg for media jobs), add systemPackages on that service in launchwithcursor.deploy.json at the repo root:
"systemPackages": ["ffmpeg"]
LaunchWithCursor installs Alpine packages in the hosted runtime image. Your AI assistant updates the manifest, then you Sync from repo on Deploy and redeploy that service.
One important exception.
systemPackagesis applied only when LaunchWithCursor builds the image for you (Next.js/NestJS apps with no Dockerfile, or Nixpacks for other stacks). If your project uses its own Dockerfile ("useDockerfile": truein the manifest), that field is ignored with no warning — the binary simply won't be there at runtime. In that case the binary must be installed inside the Dockerfile, on its final stage, along with any files it reads (for example, ffmpeg's text watermarking needs a font file, not just the ffmpeg package).
Either way, the fix is a manifest change or a Dockerfile change — never both. If a build looks fine but the media feature quietly does nothing, ask your assistant to verify the binary is actually present in the final image and to add a startup check that logs it.
The setup skill in .launchwithcursor/pack/LAUNCHWITHCURSOR/SETUP.md and SKILLS/Infrastructure.md explain this for your coding assistant.
Environment variables
Env vars are settings and secrets your apps read at runtime. List names in .env.example (committed to GitHub); keep real values in local .env and copy them into Deploy → Env vars.
When you provision add-ons, LaunchWithCursor injects managed variables automatically (for example DATABASE_URL, REDIS_URL, R2_*, EMAIL_*). Your AI coding assistant will reference these from the extension pack — you usually do not set them by hand.
For Redis, REDIS_KEY_PREFIX keeps this app's data separate from other hosted apps — your assistant should apply it to keys and Pub/Sub channel names alike, because channels are shared across the whole instance.
Full primer: Environment variables.
Domains for your apps
Each deployed service already has a free HTTPS URL on *.prod.apps.launchwithcursor.com or *.staging.apps.launchwithcursor.com. Open it from Deploy → Overview. Use those URLs for NEXT_PUBLIC_* and CORS until you add a brand domain.
To add a branded hostname (www.yourbrand.com → web, api.yourbrand.com → api), attach it on Deploy → Domains. The free platform URL stays listed — it is not replaced.
The root domain for a custom hostname must already belong to your organization:
- Register a new name under Org → Domains → Register a new domain, or
- Connect DNS for a domain you own elsewhere (Org → Domains → Connect existing domain — you keep registration at your current seller), or
- Full registrar transfer (optional) if you want to renew through LaunchWithCursor later — available after DNS is connected.
Then attach subdomains per app on Deploy → Domains. DNS records for custom hostnames are created when you deploy. Platform URLs use wildcard DNS and need no extra record from you.
Email sender domain
When you enable Deploy → Email, you must verify a sender domain before messages reliably reach users' inboxes.
You can often use the same public domain as your website (e.g. verify yourbrand.com and send from [email protected]). Follow the DNS steps on the Email tab; managed EMAIL_* env vars are injected when setup completes.
Business email (support@ → Gmail)
For founder-facing addresses (not app transactional mail), use Org → Domains → your domain → Business email:
- Select SPF providers (Gmail send-as, forwarding, app email) and Apply SPF
- Enable email forwarding, then add e.g.
support→ your Gmail - Follow the Gmail setup guide for Send mail as in the Gmail app
App email (SES) and business forwarding use different flows — both can share one domain when SPF is merged correctly.
R2 storage and production URLs
Provisioning Deploy → Storage creates a bucket and managed R2_* credentials. For early testing, a default public URL may be enough.
When real users will load uploaded files (avatars, downloads, product images), attach a custom domain on the Storage tab (e.g. cdn.yourbrand.com). That domain must be on LaunchWithCursor — bought or DNS-connected — then redeploy the API so R2_PUBLIC_URL is picked up.
Deployment problems vs runtime problems
Two different log sources — use the right one when asking your AI coding assistant in Ask mode first (investigate and explain before fixing).
Deployment failed (build never succeeded)
The app did not start. Open Deploy → Deployments, expand the failed run, click Copy log, and paste the full log into your coding assistant. Ask it to explain what went wrong and recommend a fix; switch to Agent mode only when you agree with the plan.
Typical causes: missing env var, database not provisioned, TypeScript error, migration failure.
Deploy succeeded but the app misbehaves
The build passed but using the site feels wrong (500 errors, blank page, login broken). Open Deploy → Logs, choose the app (api, web, admin) from the dropdown, reproduce the issue, then Copy log and paste into your assistant the same way.
Build output stays on Deployments; live container output stays on Logs.
First deploy checklist (summary)
- Extension installed and project synced.
- Deploy → Checklist green or understood gaps.
- Provision Database / Redis / Storage / Email if your product needs them.
- Set Env vars (copy from local
.env; skip managed keys). - Domains attached per app.
- Deploy api first when applicable, then web / admin.
- Smoke-test in the browser — logs alone are not enough.
After production is stable, run through Manual testing before sharing widely.
When in doubt, ask your assistant
You do not need to memorize platform internals. If a tab, error, or checklist item is unclear, paste the message or screenshot into your AI coding assistant. The extension pack in your repo gives it the context to answer in plain language.
Related guides
- Sample prompts — planning prompts for LaunchWithCursor
- Git & GitHub — repos, branches, staging vs production
- Environment variables —
.envvs dashboard - Transfer ownership — GitHub access after handoffs
- Install & sign in — extension setup