omg/docs

Deploy from a local machine

Test the omg CLI locally, run your app in development, and publish repeatable versions to one live URL.

The omg CLI can run an app on your computer and deploy its source to https://<slug>.omgs.app. Install it from npm; you do not need access to the omg source repository.

Before you start

You need:

  • Bun
  • an omg account
  • an internet connection for sign-in and deploys
  • an existing JavaScript app, or a name for a new one

An existing app needs a package.json with a build script. It also needs a dev script to use omg dev.

1. Install the CLI

Install the omg command globally:

npm install --global @omg-dev/cli
omg help

The executable uses Bun, so install Bun first even when npm downloads the package. You can use Bun for the global install too:

bun add --global @omg-dev/cli
omg help

For a one-off command without a global install:

npx --yes @omg-dev/cli@latest help
# or
bunx @omg-dev/cli@latest help

2. Create a new app

Skip this step if you already have an app. The shortest starter command is:

omg create my-app
cd my-app

The official create-omg generator also follows the standard Bun and npm conventions. These commands create the same starter:

bun create omg my-app
# or
npx --yes create-omg@latest my-app

The generator copies the official React + TypeScript starter and runs bun install. Pass --no-install if you only want the files.

3. Sign in and verify the account

For an interactive computer, start browser sign-in:

omg login
omg whoami

omg login opens auth.omg.dev, completes OAuth 2.1 with PKCE, and saves refreshable credentials to ~/.omg/credentials.json with owner-only permissions. omg whoami prints the account name, email, and user ID. It never prints the access token or API key.

On an SSH or other headless machine, omg login prints an authorization URL. Open it in a browser, then paste the full callback URL or authorization code into the terminal.

API-key auth for CI and automation

Browser login is enough for interactive deploys. For CI or other unattended automation, create an omg_sk_ API key at app.omg.dev/sandbox/keys. The plaintext key is shown once.

Read the key without putting it in shell history:

printf 'Paste your omg API key: '
read -r -s OMG_API_KEY
printf '\n'
export OMG_API_KEY
omg whoami

OMG_API_KEY takes precedence over saved browser credentials. For CI, put the same variable in the CI provider's encrypted secret store; never write the key into a repository, command, log, screenshot, or issue.

If you prefer an owner-only credential file on a personal headless machine:

omg login --token "$OMG_API_KEY"
unset OMG_API_KEY
omg whoami

This stores the key in ~/.omg/credentials.json with mode 0600. Treat it like a password: the key can create billable sandboxes and deploy code as you.

4. Run the app locally

Change into the root of your app and start the local emulator:

cd /path/to/your/app
bun install
omg dev

omg dev starts a local emulator and then runs your project's bun run dev. The app uses local SQLite at .vibes/data.db; emulated billing, storage, and media state lives under .omg/cache/. Cron, events, workflows, and realtime updates run locally. Stop both processes with Ctrl-C.

Local AI calls use your own provider configuration, such as ANTHROPIC_API_KEY or OPENAI_API_KEY. The default local emulator does not need an omg credential and does not deploy anything.

Do not use omg dev --cloud for normal testing. That mode currently returns 501 for VM-service requests because the public service-token broker is not available.

5. Make the first deploy

Use the API-key authentication above, then run this from the directory that contains your app's package.json:

omg deploy --name "My App"

The command uploads source, creates a short-lived staging sandbox, asks the normal omg builder to run the production build, and waits for the deploy to become ready. When it succeeds, it prints a live URL such as:

https://my-app-a1b2c.omgs.app

It also prints Manage: https://app.omg.dev/<slug>. That dashboard page is created from the same project record and contains settings, data, activity, versions, and Icon Studio for the deployed app.

Use --no-wait if you want the command to return after the build is accepted:

omg deploy --name "My App" --no-wait
omg status

CLI-deployed apps use a lightweight placeholder in the dashboard and do not spend media credits generating an app icon by default. To opt in for a new app, add this to its package.json before the first deploy:

{
  "omg": {
    "generateIcon": true
  }
}

The setting only affects initial project creation. Later deploys keep the project's existing icon; use Icon Studio in the dashboard to generate or change one afterward.

6. Keep the same slug on later deploys

The first successful deploy creates .omg/project.json:

{
  "slug": "my-app-a1b2c",
  "projectId": "project-id",
  "name": "My App"
}

The projectId is the directory's link to the omg project. A later deploy sends that ID back to the platform, which creates a new version of the same app and preserves its slug:

omg deploy
omg status

Do not hand-edit the file. Commit .omg/project.json if teammates and CI should deploy to the same app, or keep it in a secure backup if the link is local-only. The file contains identifiers, not a credential, and the CLI never uploads the .omg directory.

If the file is missing, or its project no longer exists on your account, the next deploy creates a new app and writes a new link. Restore the original file before deploying if you expected to keep the old slug.

What gets uploaded

The CLI uploads source files only. A fresh platform builder regenerates dependencies and production output.

Always excluded:

  • node_modules, dist, .next, .turbo, and coverage
  • .git, .omg, .vibes, and .DS_Store
  • symlinks, sockets, FIFOs, and device files

.env and .env.* files are refused and reported instead of uploaded — a secret baked into the artifact is a secret in every snapshot of it. Store them with omg env instead (below).

Files larger than 2 MB are skipped and reported. The complete source upload is limited to 40 MB; keep large media in object storage.

Environment variables

Secrets and config for the deployed app live on the platform, encrypted at rest, and are exported to your app's process at launch.

omg env                          # list (values are masked)
omg env set STRIPE_KEY=sk_live_… # set one or many
omg env rm STRIPE_KEY            # remove

To keep a value out of your shell history, read it from stdin:

omg env set STRIPE_KEY -

Moving an existing project over, or pulling config to work locally:

omg env push --file .env   # import a local .env
omg env pull --out .env    # write the real values back out (mode 0600)

Two things to know:

  • Changes apply on your next omg deploy. Setting a variable does not restart the running deploy.
  • You don't need keys for platform features. AI, media, storage, and billing are proxied with host-side credentials — omg env is for your third-party services. VIBES_* and OMG_* names are reserved and rejected.

Names must be valid shell identifiers ([A-Za-z_][A-Za-z0-9_]*). An app can hold up to 64 variables, each up to 4 KB.

Check the result

Run this inside the linked project directory:

omg status

After a successful deploy, use:

  • live app: https://<slug>.omgs.app
  • project dashboard: https://app.omg.dev/<slug>
  • this guide: https://docs.omg.dev/docs/deploy-from-local

The slug is the slug value in .omg/project.json.

Troubleshooting

Not signed in

Run omg login for browser auth, or set OMG_API_KEY securely. Confirm the selected account with omg whoami.

Deploy returns 401 after browser login

Upgrade to the latest CLI, then refresh the saved browser credential:

bun add --global @omg-dev/cli@latest
omg login
omg deploy

No package.json or no build script

Run the command from the app root, or point it there explicitly:

omg deploy --dir /path/to/your/app

Add a working build script to that project's package.json.

A file was skipped

The CLI reports secret files and files over 2 MB. Move secrets to project settings and large assets to storage. Generated directories and symlinks are always excluded without upload.

The build is still running

The CLI waits up to eight minutes. The server may still be building after the local wait ends:

omg status

You can also open https://app.omg.dev/<slug> to inspect the project.

A repeat deploy created a different slug

Check .omg/project.json. A missing or stale projectId means the directory is no longer linked to the original app. Restore the correct file before deploying again.

omg dev exits immediately

Confirm the project has a working dev script:

bun run dev

Fix that local command first, then rerun omg dev.