Wix CLI, September to November 2026, measured on three of our own apps. CLI behaviour may change.
npx wix release uploads whatever is in dist/ and creates a version. It doesn't run your build. If that sentence is obvious to you, the rest of this post is about how to prove what actually went live, which turned out to be less obvious than it sounds.
What happened
On 2026-09-19 we fixed a dashboard bug in our calendar app, ran the test suite (green, type check included), and released:
npx wix release -t minor -c "..." ... Uploaded successfully Preview created Version 2.17.0 was created There is no build step in that log. We didn't notice. We opened the dashboard to confirm the fix and saw the old behaviour.
To rule out a cache, we downloaded the bundle from the new deployment host and compared it with the local dist/:
cmp /tmp/live-wrapper.js dist/<path>/wrapper.CeNtilzv.js && echo identical Identical, byte for byte. The local dist/ was from the previous evening at 20:22, before the fix. npm run build changed the chunk hash from wrapper.CeNtilzv.js to wrapper.5MoEAcz1.js, and version 2.18.0 carried the fix. We burned a version number, no merchant was affected, and we've kept one rule since: test, build, release, in that order.
Why it is easy to miss
The release output looks complete. "Uploaded successfully" reads like "built and uploaded". And a stale dist/ is a perfectly valid artifact: it uploads fine, the version is created, the dashboard loads. Nothing fails. The only symptom is that your change is not there, and the first explanation that comes to mind is a cache.
How to prove what is live
We nearly fooled ourselves twice while checking 2.17.0, so here is the checklist we use now.
Step 1, find the current deployment host. Every release gets a new host, <prefix>-<app-slug>.wix-host.com. The dashboard runs on the latest deployment the moment the release completes, so the first segment of the dashboard iframe's hostname is the current prefix. Old hosts stay online and keep answering 200 for their old assets, so measuring against an old prefix will say "nothing changed" for ever. Our first attempt took two prefixes from .wix/debug.log. Both were dead and returned 500 for everything.
Step 2, use a control group. On the host you believe is current, request three things: a path that does not exist, the old bundle filename, and the new bundle filename.
| Request on the current host | Expected |
|---|---|
| a path that does not exist | 500 |
old chunk wrapper.CeNtilzv.js | 500 |
new chunk wrapper.5MoEAcz1.js | 200 |
If all three are 500, your host is wrong, not your release. Without that first row, a 500 for the old bundle looks like proof the new code is live. It isn't, and we were one step from writing that down.
Step 3, don't grep -c a minified bundle. It is one line, so the count is 0 or 1. We read a "1" as "the new string is in there". grep -o '<string>' bundle.js | wc -l on the same file said 0. The most reliable check is cmp against your local dist/.
Step 4, ship a build stamp. Our build now writes its timestamp into a static file under public/, which each deployment host serves at /_wix/extensions/public/build. Comparing a host with your local build becomes one request. We still run cmp on the bundle for anything that matters.
Running it from a script
wix release draws an interactive UI. From a non-interactive shell it dies with a raw-mode error (NonInteractiveTerminal, or a complaint about isRawModeSupported) and creates no version, which is at least a clean failure. Two flags are both required to make it non-interactive: --version-type and --comment. With only -t minor it still stops at the comment prompt.
From a plain bash with no TTY we wrap it in script:
npm test && npm run build && \ script -q /tmp/release.txt npx wix release -t minor -c "What changed, in one line" < /dev/null > /dev/null 2>&1 tr -d '\r' < /tmp/release.txt | grep -E 'Version .* was created' Two things we hit. Piping the output to tail shows nothing until the process exits, so you cannot tell "stuck" from "working"; read the typescript file instead. And --version-type accepts only major and minor. Passing patch is rejected with argument 'patch' is invalid. Allowed choices are major, minor. Every fix is therefore a minor bump, and after a 2.0.0 the next minor is 2.1.0, not 2.0.1.
Our release scripts also check that HEAD is the intended commit and the working tree is clean before calling release, tee the output into a dated report file, and grep for the "was created" line. Every call to wix release creates a version. If the line is missing, read the Versions page in the Dev Center before running it again.
What deploys without a release, and what needs one
- Backend event handlers deploy immediately, independent of the version you release. The CLI prints a warning about this, and the warning is accurate.
- Listing descriptions need a release to reach the published listing. On 2026-10-16 we edited the description and the pricing-benefit lines of one app and clicked "Update Market Listing". The benefit lines went live at once; the description stayed old in the published record, and the version indicator kept saying "Up to date". A
wix release -t minorwith unchanged code pushed the new description to all nine languages within seconds. - Pricing edits can lock releases. On 2026-10-12 a change to a plan's benefit text put the app into "App submitted for review", and
wix releasefailed withFailed Precondition … App with app id '…' is not editablefor more than two days. A later pricing edit on another app did not trigger the lock. We don't know what decides it; we just finish code releases before touching pricing fields. -
wix previewlets you look before you create a version.npm run build && npx wix previewprints aversionOverrideId. Open the dashboard with?apps-override=<that id>to see the build without releasing.
Where it still bites
- The upload is only the start. For storefront widgets, visitors receive the new deployment when Wix next renders their page, and that render can be cached for hours (we have measured up to 35; that is a separate post). Verify with a cache-busting query on your own site, then
cmp. - Tests that look at
dist/test thedist/you have. Some of ours scan the build output for secret names and absolute local paths. Run those after the build, or a green run is reporting on yesterday's artifact. - Our build does more than
wix build. It also strips absolute local paths out ofdist/before anything is uploaded. If you add steps like that,wix releasewill not run them for you either.
The whole lesson fits in one line of a shell script: put the build in the script, because the release command won't do it for you.
Written by a backend engineer with ten years of experience, building small Wix and Shopify apps as operix.
The calendar app from the 2.17.0 story is on the Wix App Market: https://www.wix.com/app-market/a5d62bae-8405-4635-a985-8743d9ad50d7?utm_source=blog&utm_medium=article&utm_campaign=wix-release-does-not-build

