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 helpThe 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 helpFor a one-off command without a global install:
npx --yes @omg-dev/cli@latest help
# or
bunx @omg-dev/cli@latest help2. Create a new app
Skip this step if you already have an app. The shortest starter command is:
omg create my-app
cd my-appThe 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-appThe 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 whoamiomg 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 whoamiOMG_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 whoamiThis 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 devomg 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.appIt 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 statusCLI-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 statusDo 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, andcoverage.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 # removeTo 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 envis for your third-party services.VIBES_*andOMG_*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 statusAfter 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 deployNo package.json or no build script
Run the command from the app root, or point it there explicitly:
omg deploy --dir /path/to/your/appAdd 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 statusYou 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 devFix that local command first, then rerun omg dev.