Skip to main content
This is how a change gets from your editor to production. The steps are the same whether you work alone or on a team, and each one is a single command.
Each change goes from a git branch to its own preview, through a pull request, and into main. A release is cut once, tagged v1.4.0, and that same release is shipped to dev, stage, and prod.Each change goes from a git branch to its own preview, through a pull request, and into main. A release is cut once, tagged v1.4.0, and that same release is shipped to dev, stage, and prod.
Each change goes from a git branch to its own preview, through a pull request, and into main. A release is cut once, tagged v1.4.0, and that same release is shipped to dev, stage, and prod.Each change goes from a git branch to its own preview, through a pull request, and into main. A release is cut once, tagged v1.4.0, and that same release is shipped to dev, stage, and prod.

A preview for every change

Each branch gets its own live copy of your backend. Nothing you try there can touch anyone else.

Test once, ship everywhere

A release is a saved, numbered version of your backend. The release that passed stage is the exact one that reaches prod.

Undo in one command

Production always runs a release. To go back, ship the one before it.
Git is the source of truth. Your code lives in a GitHub repo, and main holds what production runs or is about to run. If your team builds in the Xano builder instead, the same flow works: see If Xano is your source of truth.

Where your backend runs

With a tenant stack, every change gets an ephemeral, and releases go to dev, stage, and prod tenants, each with its own database. Without tenants, ephemerals work the same and your workspace is production.With a tenant stack, every change gets an ephemeral, and releases go to dev, stage, and prod tenants, each with its own database. Without tenants, ephemerals work the same and your workspace is production.
With a tenant stack, every change gets an ephemeral, and releases go to dev, stage, and prod tenants, each with its own database. Without tenants, ephemerals work the same and your workspace is production.With a tenant stack, every change gets an ephemeral, and releases go to dev, stage, and prod tenants, each with its own database. Without tenants, ephemerals work the same and your workspace is production.
Everything below is the same with or without tenants. Only the last step changes.

Set up once

Push the repo to GitHub. On a team, protect main so changes only arrive through pull requests. Using tenants? Create them in the Xano dashboard, then give each one its own secrets. env set reads the value from a file or a pipe, so it never appears on screen:

The workflow

1

Branch, and get a preview

deploy --ephemeral puts your branch on your own ephemeral, runs your tests, and prints the URL. It is yours alone, so deploy to it as often as you like. (A bare deploy goes to the Xano Engine on your machine, which nobody else can open.)
2

Open a pull request

CI gives the pull request its own ephemeral too, so reviewers click through a running app instead of only reading a diff. They also check four things specific to the Xano SDK.
3

Merge to main

Merge once it is approved. Keep main releasable: anything merged there can ship.
4

Cut a release

A release never changes once it is created, and giving it the same name as the git tag means every release points back to its exact code. To change anything, cut v1.4.1. Cut from the ephemeral, not the Xano Engine (why). With CI set up, pushing the tag does all of this for you.
5

Ship it

Check each one before moving to the next. Shipping a frontend too? Build it once from the tag and publish the same build to each tenant. It picks up that tenant’s URL on its own:
A tenant deploy makes the tenant match the release exactly. Anything not in the release is removed, including tables and the data in them. Before you ship a release that removes or changes a table, back up prod in the Xano dashboard and preview the change:
Each landing is recorded in xano/xano.lock. Commit the lock afterwards, so the next deploy --to … --prune knows what this project put there.

Solo or team

The steps are the same. A team adds review and approval.

When something goes wrong

Prod was running v1.4.0, which turned out to be bad. Deploying v1.3.2 to prod puts the previous release back. The fix then ships as v1.4.1.Prod was running v1.4.0, which turned out to be bad. Deploying v1.3.2 to prod puts the previous release back. The fix then ships as v1.4.1.
Prod was running v1.4.0, which turned out to be bad. Deploying v1.3.2 to prod puts the previous release back. The fix then ships as v1.4.1.Prod was running v1.4.0, which turned out to be bad. Deploying v1.3.2 to prod puts the previous release back. The fix then ships as v1.4.1.
Production always runs a release, so going back means serving the previous one:
With the workspace, <previous branch> is the Xano branch that was live before the promote (xanosdk workspace branch list shows them). Table changes are not rolled back by either command: see Rollback and recovery. Then fix the problem on main and ship v1.4.1. Until main is fixed, the next release brings the problem back.
A rollback restores your logic, not your data. If the bad release dropped a table or a column, it comes back empty. Your backup is how you recover the rows.
Hotfixes follow the same steps: branch, review, merge, release v1.4.1. This is why main stays releasable. If it holds unfinished work, branch from the tag instead (git switch -c hotfix v1.4.0) and merge the fix back into main afterwards. Do not edit production by hand. A tenant deploy replaces anything edited directly. To look around safely, open a tenant read-only with xanosdk impersonate tenant:prod --guest. Made an emergency fix in the Xano builder? With the workspace as production, that is sometimes the fastest option. Bring the fix into git the same day, before the next release overwrites it, then open a pull request:

If Xano is your source of truth

Two ways to author, one way to ship. With git as the source of truth, changes go from a git branch through a pull request into main. With Xano as the source of truth, changes go from a Xano branch through review in the builder to the live branch, and you sync git at each release. Both produce a release that ships to the same environments.Two ways to author, one way to ship. With git as the source of truth, changes go from a git branch through a pull request into main. With Xano as the source of truth, changes go from a Xano branch through review in the builder to the live branch, and you sync git at each release. Both produce a release that ships to the same environments.
Two ways to author, one way to ship. With git as the source of truth, changes go from a git branch through a pull request into main. With Xano as the source of truth, changes go from a Xano branch through review in the builder to the live branch, and you sync git at each release. Both produce a release that ships to the same environments.Two ways to author, one way to ship. With git as the source of truth, changes go from a git branch through a pull request into main. With Xano as the source of truth, changes go from a Xano branch through review in the builder to the live branch, and you sync git at each release. Both produce a release that ships to the same environments.
Some teams build in the Xano builder rather than in code. You get the same releases, environments, and rollbacks. Two things change: you make and review changes in the workspace, and you keep git in sync yourself. Five practices keep this safe:
  1. Never edit the live Xano branch. Make each change on its own Xano branch and serve it once it is reviewed. Without tenants, serving it is also your production release.
  2. Keep Xano branches small and short-lived. There is no merge tool: if two people change the same object on different Xano branches, the one served second replaces the other’s work.
  3. Treat table changes with care. Every Xano branch shares the same tables, so adding or dropping a column changes the live workspace right away.
  4. Sync git at every release. Git becomes your history and your backup:
  5. Never push from git to the workspace. Running promote or deploy --to workspace from the repo makes git a second source of truth, and someone’s work gets overwritten. To switch to git as the source of truth later, start at Set up once.

Automate it with GitHub Actions

With this in place, every pull request gets its own preview, pushing a tag releases to dev, and one click ships to stage or prod. CI signs in with three repository secrets instead of xanosdk login: XANO_INSTANCE_URL, XANO_WORKSPACE_ID, and XANO_META_TOKEN (see Environment variables).
  • A failing test stops a tag from becoming a release. Delete the tag (git push --delete origin v1.4.0), fix main, and tag again.
  • A forgotten xano/xano.lock fails the run before anything lands. On a pull request, npm run xano:check stops the preview before it deploys. It runs xanosdk export ./xano/index.ts --check --strict, which implies --frozen-lock and needs no secrets. On a tag, the release deploy passes --frozen-lock itself.
  • The landing comes back as a pull request. A tenant deploy or promote records what it landed in xano/xano.lock, in CI’s checkout. The last step of each landing job opens a pull request with that change; merge it like any other. It needs “Allow GitHub Actions to create and approve pull requests” turned on in the repository’s Actions settings.
  • Never re-run a step that exited 9. Exit 9 means the write was sent and the answer was lost, so it may have landed. A retried release create can leave a second release under a suffixed name. Run the resolveWith command the step printed, or check with xanosdk release list and xanosdk tenant get <tenant>, before anything else. See Exit codes and outcomes.
  • No tenants? In release, drop the two lines that ship to dev. In ship, run npx xanosdk promote "$RELEASE" --set-live --yes and publish --to workspace. A release that alters a table is refused (exit 2, SDK_SHARED_SCHEMA_CHANGE) until you add --allow-shared-schema-changes; read Schema changes before you put that flag in a workflow.

The rules

  1. One source of truth. Git by default, Xano if your team builds there, never both.
  2. Every change gets a branch and a preview.
  3. Only releases reach production, and the same release goes everywhere. Environments differ by their secrets, never by their code.
  4. Roll back by shipping the previous release. Back up first when a release changes a table.
  5. Commit xano/xano.lock. Never commit secrets.

Where to go next

Git, locks & merges

What to commit, resolving a xano.lock conflict, renames, and the review checklist.

Releases

The details underneath: cutting, listing, and landing releases, and Xano branches.