# Deployment

URL: https://ship-and-scale.vercel.app/docs/start/deployment-kickstart

Put your app online with a private GitHub repository and Vercel hosting.

Deployment Kickstart takes the app you've been running locally and puts it online. It creates a private GitHub repository for your code, a Vercel project that hosts it, and live versions of your email and billing settings. When it finishes, you get a public address for your app.

Start when sign-up and sign-in work in your local app. You'll add a few more keys to the same `.env`, run two commands, then test the live app.

## What this workflow does [#what-this-workflow-does]

<div className="docs-accounts-table">
  | Kickstart creates         | Details                                                                                                     |
  | ------------------------- | ----------------------------------------------------------------------------------------------------------- |
  | Private GitHub repository | Owned by your GitHub account. It contains your current source code, without the starter's Git history.      |
  | Vercel project            | Connected to that repository and configured with only the settings your app needs to run.                   |
  | Live billing              | Copies your Stripe test products and prices into live mode and sets up the live webhook and billing portal. |
  | Production address        | A `vercel.app` address by default, or your own domain. Sign-in, emails and integrations switch to it.       |
</div>

Deployment doesn't push anything to the Ship & Scale repository or change your local folder's Git history. Your local folder stays as it is; after deployment, you'll continue working from a clone of the new repository.

## Finish local setup first [#finish-local-setup-first]

### Check your local app [#check-your-local-app]

Complete [Kickstart](/docs/start/project-kickstart) and confirm you can sign up, sign in and reach your dashboard locally. Keep `.env`, `.kickstart` and `.secrets` in your project folder; deployment uses the settings Kickstart saved there.

### Prepare the deployment accounts [#prepare-the-deployment-accounts]

Follow each guide, then return here:

| Requirement                               | Guide                                                      | Why you need it                                            |
| ----------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
| GitHub access token                       | [GitHub](/docs/accounts/github)                            | Creates your private repository and uploads your code      |
| Vercel access token and GitHub connection | [Vercel](/docs/accounts/vercel)                            | Creates the hosting project and lets Vercel read your code |
| Verified sending domain                   | [Resend](/docs/accounts/resend#verify-a-production-sender) | Lets your app email any customer, not only you             |
| Stripe live secret key                    | [Stripe](/docs/accounts/stripe#live-secret-key)            | Needed when billing is enabled                             |

All of these work on free plans. Vercel's Hobby plan is for non-commercial use, so move to Pro before you take payments. You'll need a domain for the email sender; if you don't have one yet, buy it from any domain registrar.

### Add the deployment values [#add-the-deployment-values]

Open the same `.env` and add these values, keeping everything that's already there:

```dotenv title="Your private .env"
GITHUB_TOKEN=replace_with_your_github_token
VERCEL_TOKEN=replace_with_your_vercel_token
STRIPE_LIVE_SECRET_KEY=sk_live_REPLACE_WITH_YOUR_KEY
RESEND_FROM_EMAIL=noreply@your-verified-domain.example
RESEND_TEST_MODE=false
```

Use an address under your verified domain for `RESEND_FROM_EMAIL`. Keep `STRIPE_TEST_SECRET_KEY` on its own line. Deployment copies your Stripe test products and prices into live mode, so check their names and amounts in your Stripe sandbox first. If your contact form should reach a specific inbox, set `CONTACT_TO_EMAIL` as well.

Leave `GITHUB_OWNER`, `GITHUB_REPO_NAME`, `GITHUB_REPO_ID`, the `VERCEL_*` IDs and `APP_URL_LIVE` blank. Kickstart finds your GitHub account and Vercel team, names the repository and project after `APP_NAME`, and fills these in.

### Choose your address [#choose-your-address]

By default, your app gets a free address such as `your-app.vercel.app`. You can switch to your own domain at this point, but **decide before your first deployment**: changing the address after launch is a manual process, because sign-in and email links depend on it.

To use your own domain, follow [Use your own domain](#use-your-own-domain) below before running the commands.

## Check, then deploy [#check-then-deploy]

### Run the read-only check [#run-the-read-only-check]

```sh
npm run kickstart:deploy -- --check
```

This checks your tokens, accounts, repository access and settings without creating anything. Fix every reported failure before continuing. A passing check confirms access; it can't guarantee that every later step will succeed.

### Deploy [#deploy]

**This command changes your live accounts**

Deployment creates a GitHub repository, a Vercel project and live Stripe products. It also switches your shared Supabase sign-in and email settings to the production address. Check that you're using the intended accounts before running it.

```sh
npm run kickstart:deploy
```

If you can access several Vercel teams, the terminal asks which one to use. Leave the terminal open while it runs. Kickstart saves IDs to `.env` as it creates each resource, so a rerun continues where it stopped.

If Vercel can only access selected repositories, Kickstart pauses after creating your repository and shows a link. Open it, add the new repository to the Vercel GitHub App, then run the same command again.

When deployment finishes, Kickstart checks that your home page and login page load over HTTPS and prints your app's address.

### Test your live app [#test-your-live-app]

Open the address Kickstart printed and check the main customer flows:

1. Sign up with an email address, complete or skip onboarding and confirm you land in your own workspace.
2. Sign out, then sign in again.
3. Request a password reset and confirm the email arrives from your domain.
4. Invite a second email address to your workspace and accept the invitation.
5. If billing is enabled, follow the [subscription checks](/docs/billing/subscriptions#verify-a-test-purchase) before opening sales.

The deployment check confirms the site is online. These steps confirm your customers can actually use it.

### Switch to your new repository [#switch-to-your-new-repository]

From now on, work in a clone of the repository Kickstart created, not the starter folder:

1. Clone the new repository from GitHub into a new folder.
2. Copy your `.env` file from the starter folder into the new folder. Git doesn't include it, and your app needs it to run locally.
3. Run `npm ci`, then `npm run dev` to confirm the app starts.

Keep the original starter folder with its `.kickstart` and `.secrets` files. They record what Kickstart created and you'll need them if you ever rerun or recover deployment. Back them up somewhere private, such as an encrypted drive or password manager.

To release a change, commit it in your new repository and push to `main`. Vercel builds and deploys each push automatically.

## Use your own domain [#use-your-own-domain]

Set this up before your first deployment:

1. Set `APP_URL_LIVE` in `.env` to your domain's HTTPS address, such as `https://app.your-domain.com`, without a path.
2. Run `npm run kickstart:deploy`. Kickstart creates the Vercel project and adds your domain to it, then stops because the domain isn't connected yet. Sign-in settings haven't changed at this point.
3. In Vercel, open your project's **Settings → Domains**. Add the DNS records it shows at your domain provider. See [Vercel's domain guide](https://vercel.com/docs/domains/working-with-domains/add-a-domain).
4. Wait until Vercel shows the domain as verified, then run `npm run kickstart:deploy` again.

To change the domain after launch, follow [Domains, updates and deployment recovery](/docs/operations/deployment#assigned-and-custom-domains).

## After deployment [#after-deployment]

Your local app and your live app share one Supabase project. After deployment, sign-in links, emails and connected integrations point to your live address, even when you're testing locally, and anything you create locally lands in the same database your customers use. [Where your app runs](/docs/build/codebase#where-your-app-runs) explains this setup.

Don't rerun the local `npm run kickstart` after launch. It would try to switch sign-in back to your local address, which affects your live customers. If you really need that, read [active and saved origins](/docs/operations/deployment#active-and-saved-origins) first.

Vercel preview deployments are turned off because they can't share your production sign-in settings.

**Technical details: what enters production**

Kickstart publishes the source roots listed in `config/deployment.json`. `scripts/kickstart/deploy-source.mjs` excludes environment files, setup receipts, dependencies, builds, screenshots and local scratch folders, and scans for recognizable secret values. A pattern scanner can't recognize every private document, so review any content you've added to public folders.

Production environment variables come from the explicit allowlist in `scripts/kickstart/deploy-config.mjs`. Setup tokens for Supabase, GitHub and Vercel are never uploaded. Server-only credentials stay server-only.

The repository starts from a clean snapshot without the starter's Git history. Adopting future starter releases is a manual merge, not an automatic update. See [updates after the first snapshot](/docs/operations/deployment#updates-after-the-first-snapshot).

If a repository already has commits Kickstart didn't record, or your source changed after Vercel was connected, deployment stops instead of overwriting your work. Push later changes through Git. [Troubleshooting](/docs/operations/troubleshooting#build-and-source-errors) covers these messages.

## You're finished when [#youre-finished-when]

* Your app loads at its live address and you can sign up, sign in and receive emails there.
* You're working from a clone of your new repository, with your `.env` copied into it.
* The original starter folder, with `.kickstart` and `.secrets`, is backed up privately.

[Next: Launch checklist](/docs/operations/launch)

Review your product, customer flows and billing before announcing your app.