ProgaTech
Contact us

Capacitor OTA Updates with Capawesome: How we ship live updates across Stridist branded apps

How Proga Tech uses Capawesome Live Update to ship safer, binary-compatible Capacitor updates across Stridist's main app and branded app variants.

10 min read

·

May 7, 2026

Capacitor OTA Updates with Capawesome: How we ship live updates across Stridist branded apps

Capacitor OTA Updates with Capawesome: How we ship live updates across Stridist branded apps

When a Capacitor app grows into a portfolio of branded variants, every UI fix risks becoming a multi-queue App Store submission marathon. For Stridist, that wasn't sustainable. The solution wasn't replacing native releases - binary changes still go through the stores. It was building a safe path for web-bundle updates across the main app and its branded variants without the overhead. Using Capawesome Live Update, we combined per-variant channels, signed bundles, startup readiness checks, and restart-based activation to make OTA updates something we could trust in production.
Here's how we did it.

Why we needed OTA updates

The core problem was release speed. When a product team ships often, store review becomes a bottleneck for small but important fixes. A bug in a workflow, a broken screen, or a UI regression becomes much more expensive when the only delivery mechanism is a full native release.
For Stridist, that meant we needed a way to:
  • save developer capacity from release management
  • deliver most app changes without waiting for store approval
  • keep the native app shell and store process for the changes that are undeliverable without it That distinction matters. OTA updates are not a replacement for native releases. They are a way to move faster for the part of the app that lives inside the web bundle
That distinction matters. OTA updates are not a replacement for native releases. They are a way to move faster for the part of the app that lives inside the web bundle.

Why OTA became more valuable once we added branded apps

For a single app, OTA updates are already useful. For a multi-app setup, they become operationally important.
Our platform now includes:
  • the main Stridist app
  • stage and production app variants
  • multiple branded apps with their own bundle identifiers and app-store presence
The repo reflects that structure directly. We maintain branded app definitions, branded app-specific assets/configuration, and multiple Capawesome Cloud app registrations. Adding a new branded app is not just a UI change. It creates another native surface that has to be built, released, and maintained.
That is where the usual mobile release model starts to hurt. Without OTA updates, every compatible web-layer change risks turning into repeated release work across multiple apps.
What OTA gave us was a way to separate two update categories:
  • native bundle changes, which remain app-specific
  • live-update-compatible changes, which can move through a shared live update path
That separation matters much more when the product is no longer one binary.

When OTA fits and when it doesn't

The fit is strongest when three things are true: you’re already on Capacitor, most frequent changes live in the web layer, and release speed matters. That was exactly our situation.
We didn’t need OPT to replace native delivery. We needed it to cover the changes that don't require it while keeping store releases for the ones that do: native plugin updates, new SDK integrations, permission changes, anything that touches the binary.
The practical rule is simple: if that boundary isn't defined before you ship, OTA updates create risk instead of removing it. Decide what belongs to each path before the first bundle goes out.

What we used

We chose @capawesome/capacitor-live-update for one straightforward reason: it fit the stack without becoming a project of its own, supported channels, gave us control over activation, and was realistic to ship without turning the update pipeline into a project of its own.
Our configuration reflects that bias toward control and safety:
There are a few important decisions inside that small block:
  • autoUpdateStrategy: "none" means we do not silently swap bundles during runtime;
  • readyTimeout gives startup a defined safety boundary;
  • autoBlockRolledBackBundles helps prevent repeatedly promoting a bad bundle;
  • defaultChannel keeps stage and production release streams separate;
  • publicKey lets us verify signed bundles in production.
This was not an “update everything automatically” setup. It was a controlled rollout model.

How Capawesome fits our multi-app setup

We use Capawesome in two different ways. For native app bundles, Capawesome Cloud builds are our direction for managing app-specific releases. That part is still evolving, so it is not the main subject of this article. What matters more in day-to-day practice is the live update layer.
For compatible changes, we don't treat every branded app as a separate release event. A bundle-level fix gets prepared once and distributed through the shared production live update channel rather than duplicated across each app's store review queue.
That gives us a cleaner split:
  • native-build changes remain per app
  • compatible OTA changes can be rolled out through the shared live update path
That’s what made OPT feel less like a convenience and more like a platform infrastructure once branded apps entered the picture. The value isn’t just shipping faster, it’s not repeating the same release work across every variant.

How we think about compatibility across multiple apps

The most important rule in a multi-app OTA setup is simple: a bundle only goes through the shared production live update channel if it is compatible with every native shell on that channel.
If compatibility depends on a newer native build, a brand-specific native change, or a shell that is no longer aligned with the others, that change does not go through the shared OTA path. It stays on the native release track for the affected app.
This is the model we use to decide delivery path:
Change type
Delivery path
Why
React UI copy or layout fix
OTA
Binary-compatible web-bundle change
Shared app-flow bug fix
OTA, if compatible with all target shells
Safe across the main app and branded variants
Brand-specific asset or config change
OTA or native, depending on where it lives
Safe if it stays inside the web bundle, native if it changes the shell
New native plugin
Native app release
Binary changes require store review
New iOS or Android permission
Native app release
Store-reviewed capability
The release planning discipline is what makes this work. Before we publish, every change is classified as either OTA-compatible or native-release-required.

The rollout model we chose

The most important design choice was not the plugin itself. It was how the updates became active.
We chose a manual, controlled activation model:
notion image
That pattern trades a little immediacy for a lot of operational safety. In practice, that means users can continue their session without a mid-flow bundle swap, while we still get the delivery speed advantage of OTA updates.
The background check follows this logic:
Today, the app checks on startup, then rechecks on a conservatively hourly interval. When a new bundle is ready, users see a simple prompt to restart. The mechanics of OTA are only half the story - activation UX matters just as much.

Why the startup lifecycle matters more with OTA

Shipping speed is the obvious benefit. Update safety is the hardest part.
Once a mobile app can boot into a remotely delivered bundle, the startup lifecycle matters much more. You need to know when a bundle is healthy, what happens when it isn’t, and how to avoid repeatedly activating a bad release.
In Stridist, that led to a very explicit startup step:
The app marks the current live-update bundle as ready before the splash screen is hidden. That gives the OTA system a clear signal that the bundle started successfully. Combined with timeout and rollback protection, this reduces the chance that a broken update becomes the app’s normal state.
Our current readyTimeout is 3000, which works for our startup path today. The general lesson is not that three seconds is universally right. It is that teams should measure real startup behavior on slower devices before choosing an aggressive timeout.
In other words, OTA updates aren’t just a deployment feature. They’re a startup contract.

Our end-to-end update flow

At a high level, the Stridist OTA flow works like this:
notion image
That flow is intentionally conservative. We did not want a model where updates could quietly rewire the current session. We wanted most app changes to move faster than store review while keeping runtime behavior understandable for both users and engineers.

What this changed for us

The immediate win was hotfix speed. Once OTA updates were in place, most app-level changes no longer had to wait for a full app-store cycle. That gave us a much shorter path from fix to delivery for the kinds of changes that happen frequently in a fast-moving product. Just as important, it improved release discipline.
The multi-app impact was just as important. One compatible fix could be prepared once and delivered through the live update channel instead of being repeated across each branded app release path.
Just as important, it improved release discipline. The team now classifies every change as native-release-required or OTA-compatible before release planning.
It forced us to be explicit about:
  • what counts as a bundle-level change
  • what still requires a native release
  • what “safe to activate” means at startup
  • how to think about updates when one product becomes many app variants
That is one of the less obvious benefits of implementing OTA updates well. The technical mechanism matters, but the release model matters more.

Final thoughts

For Stridist, OTA updates were not about novelty. They were about removing a delivery bottleneck that got bigger as the platform expanded.
We already had a Capacitor app. Then we added branded apps. That made the traditional release path more repetitive, more expensive, and slower to react to compatible app-layer changes.
Capawesome Live Update was the fastest path to solving that problem, but the real value came from the rollout model around it: signed bundles, separate channels, background download, explicit startup readiness, and restart-based activation.
Now the split is much cleaner. Native bundle updates can stay app-specific. Live-update-compatible changes can move through a shared OTA layer. For a team managing both a main app and branded apps, that is where OTA updates start to feel less like a convenience and more like platform infrastructure.

How Stridist manages Capacitor OTA Updates across branded apps

A practical guide to OTA updates with Capawesome: channels, signed bundles, and startup safety for multi-app portfolios

Contact us

Check out other posts

A production guide to graph-enhanced retrieval
AI Engineering
Cost Optimization

12 min read

Apr 29, 2026

A production guide to graph-enhanced retrieval
Capacitor OTA | Proga Tech