---
title: The Right Way to Update Your Capacitor App Remotely
description: Learn the differences between Live Updates and server.url in Capacitor and why Live Updates are the better choice for production apps.
date:
  created: 2026-04-02
  updated: 2026-07-17
authors:
  - robingenz
categories:
  - Capacitor
  - Cloud
  - Guides
links:
  - Live Update: sdks/capacitor/live-update.md
faq: true
---

# The Right Way to Update Your Capacitor App Remotely

One of the most common questions we get is: "What's the difference between using Live Updates and `server.url` in Capacitor?"
Many developers use the `server.url` configuration option to load their app's web content from a remote server in production — even though it was never designed for that.
In this post, we'll break down what each approach does, how they compare, and why Live Updates are the better choice for production apps.

<!-- more -->

<div class="capawesome-z29o10a">
  <a href="https://capawesome.io/" target="_blank">
    <img alt="Build and deploy your Capacitor app with Capawesome Cloud" src="https://capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.png?t=1" />
  </a>
</div>

## What is `server.url`?

Capacitor's [`server.url`](https://capacitorjs.com/docs/config){:target="_blank"} configuration option tells the WebView to load content from an external URL instead of the bundled app assets.
When set, the app no longer uses the local HTML, CSS, and JavaScript files that were shipped with the binary — it fetches everything from a remote server at startup.

According to the Capacitor documentation, `server.url` is **not** intended for production use. It's primarily meant for development purposes, allowing you to connect your app to a live-reload dev server so you can see changes in real time without rebuilding the app.
However, many teams also use it in production to serve their app's web content from a remote server.
It's easy to see why: with platforms like Cloudflare or Vercel, deploying an update to a static site takes seconds — making it natural to want the same workflow for your mobile app.
What many developers don't realize is that a live update can be delivered just as quickly — if you choose the right platform.

## What are Live Updates?

[Live Updates](https://capawesome.io/cloud/live-updates/){:target="_blank"} — also known as Over-the-Air (OTA) Updates — let you push changes to the web layer of your Capacitor app directly to your users' devices, without going through app store review.
Instead of loading content from a remote server on every launch, the app downloads updated web assets in the background, stores them locally, and loads them on the next restart.

The key difference is that the updated files live on the device.
Once downloaded, they behave exactly like the original bundled assets — they're fast, reliable, and available offline.
If you want to dive deeper into the mechanics, check out our blog post [How Live Updates for Capacitor Work](./how-live-updates-for-capacitor-work.md).

## Key Differences

Both approaches let you update your app's web content without submitting a new binary to the app stores.
But that's where the similarities end.

### Offline Support

With Live Updates, the web assets are stored locally on the device.
Once an update has been downloaded, your app works **fully offline** — just like a freshly installed app.

With `server.url`, the app needs an active network connection every time it launches.
**No connection means no content.**
If your users are in areas with spotty connectivity — or simply on an airplane — your app shows a blank screen or an error page.

### Performance

Local assets load **almost instantly** because there's no network round-trip involved.
The WebView reads the files directly from the device's file system, which means your app feels fast and responsive from the moment it opens.

When using `server.url`, the app has to fetch all its content from a remote server on every launch.
This adds latency that depends entirely on the user's connection quality.
On a slow or congested network, your app's startup time can increase noticeably — and that's a poor first impression.

### Reliability

With `server.url`, your remote server becomes a **single point of failure**.
If the server goes down, every user who opens the app sees nothing.
There's no fallback to the bundled assets — the app simply can't load.

Live Updates are far more resilient.
If a download fails or the server is temporarily unreachable, the app continues to use whichever version of the web assets it already has on disk — whether that's a previous update or the original bundle.
Your users may not get the latest changes immediately, but they **always get a working app**.

### Security

Live Updates support [code signing](../../cloud/live-updates/code-signing.md), which lets you verify both the **authenticity** and **integrity** of every update before it's applied.
The update bundle is signed with a private key, and the app verifies the signature using a public key before loading the new files.
This ensures that the content hasn't been tampered with and actually comes from a trusted source.

With `server.url`, the content is fetched over the network without any built-in integrity checks.
You're relying entirely on HTTPS to secure the connection, but there's no application-level verification that the content you're loading is what you intended to ship.

### Native Version Compatibility

This is the **most critical difference** — and the one that's often overlooked.

A Capacitor app consists of a web layer and a native layer.
When you update a plugin, change native configuration, or bump a native dependency, the web build **must be compatible** with the native binary.
If there's a mismatch, things break: plugin calls fail, features disappear, or the app crashes.

With `server.url`, you can only serve **one** web bundle to all users, regardless of which native version they're running.
The moment you update a plugin or change native configuration, you need the web build to match — but users who haven't updated the native app from the store will still load the new web content.
There's **no way to target different native versions** with different bundles.

Live Updates solve this problem with [Versioned Bundles and Versioned Channels](../../cloud/live-updates/index.md#binary-compatible-changes){:target="_blank"}.
Versioned Channels, for example, let you create a channel for each native version code and assign bundles accordingly.
Users on native version 10 receive updates compatible with version 10, while users on version 12 receive updates compatible with version 12.
This ensures that every user always gets a web build that matches their native binary — no matter how many native versions are in the wild.

### App Store Compliance

Live Updates are **explicitly compliant** with both [Apple App Store](https://developer.apple.com/support/terms/apple-developer-program-license-agreement/){:target="_blank"} and [Google Play](https://support.google.com/googleplay/android-developer/answer/9888379/){:target="_blank"} policies.
Apple allows downloading interpreted code as long as it doesn't change the app's primary purpose.
Google's policy exempts JavaScript running in a WebView from its restriction on self-updating apps.

Using `server.url` to load an entirely remote app is a grayer area.
While it technically still runs JavaScript in a WebView, app reviewers may question an app that's essentially an empty shell loading all its content from a server — especially if the content changes significantly after review.
In fact, a member of the Ionic team has [pointed out](https://github.com/ionic-team/capacitor/discussions/4080#discussioncomment-873991){:target="_blank"} that while Apple allows apps to run code not embedded in the binary, Capacitor plugins don't work in a standard WebKit view — which puts `server.url` in a gray area under [Section 4.7](https://developer.apple.com/app-store/review/guidelines/#third-party-software){:target="_blank"} of Apple's App Store Review Guidelines.
They also confirmed that `server.url` was only added for live-reload during development and is not recommended for production use.

## When `server.url` Still Makes Sense

To be fair, `server.url` has its place — it's just not in production.

During development, it's an excellent way to connect your app to a local live-reload server so you can see changes in real time without rebuilding the app.
This is exactly what it was designed for, and it works great in that context.

It can also be acceptable for internal enterprise tools where offline support, performance, and app store compliance aren't concerns — for example, a kiosk app that's always connected to a local network.

But for any app that's distributed to end users through the app stores, Live Updates are the better choice.

[Try Capawesome Cloud Free](https://capawesome.io){ .md-button .md-button--primary }

## FAQ

### Is `server.url` ever actually against app store rules, or just risky?

It's a gray area rather than an explicit violation. Apple's guidelines allow downloading interpreted code as long as it doesn't change the app's primary purpose, but a member of the Ionic team has pointed out that Capacitor plugins don't function in a standard WebKit view — which pushes an all-remote `server.url` setup into Section 4.7 territory, and Apple's own team confirmed the option was only ever intended for development. It's not automatically rejected, but it's not a safe production default either.

### If my app already uses `server.url` in production, how hard is it to switch to Live Updates?

The migration is mostly configuration, not a rewrite. You stop pointing the WebView at a remote URL and instead ship your web build as the app's bundled assets, then use Live Updates to push subsequent changes — your actual web app code doesn't need to change, since Live Updates load the same kind of HTML/CSS/JS output that `server.url` was fetching remotely.

### Does `server.url` at least give me faster updates than Live Updates, since there's no download-and-restart cycle?

Not really, once you account for the practical difference. `server.url` fetches content over the network on every single app launch, which adds latency on every open, whereas a Live Update downloads once in the background and then loads from local disk on every subsequent launch — faster overall despite the extra step of installing the bundle.

### Is there any legitimate production use case for `server.url`?

Yes, in narrow cases — internal enterprise or kiosk apps that are always on a local network, where offline support, performance, and app store compliance aren't real concerns. Outside of that, and outside of local development with a live-reload server (its actual intended use), Live Updates are the better fit for anything distributed to end users through the app stores.

### Can `server.url` serve different content to different native app versions the way Live Updates channels can?

No — this is the compatibility gap the post calls out as most overlooked. `server.url` serves one URL to every user regardless of which native version they're running, so if you update a plugin or native config, there's no way to keep users on an older native binary from loading web content built for a newer one. Live Updates' versioned channels solve exactly this by pinning bundles to specific native version codes.

## Related Posts

- [Announcing the Live Update Plugin for Capacitor](./announcing-the-capacitor-live-update-plugin.md)
- [Capacitor Live Updates: The Complete OTA Guide](./capacitor-live-updates-guide.md)

## Conclusion

`server.url` was designed as a development tool, not a production deployment strategy.
While it can technically serve your app's web content from a remote server, it comes with significant trade-offs: no offline support, slower performance, no fallback when the server is down, no code signing, no native version targeting, and potential app store compliance concerns.

Live Updates give you the same core benefit — updating your app's web content without going through app store review — while keeping your assets local, fast, and secure.
With features like Versioned Channels, you can safely manage multiple native versions in the field without worrying about compatibility issues.

If you're interested in related topics, check out [Capacitor App Updates: The Complete Guide](./capacitor-app-update-guide.md) for a complete strategy that combines live updates with native app store updates.
Join the [Capawesome Discord server](https://discord.gg/VCXxSVjefW){:target="_blank"} if you have questions or want to connect with the community, and subscribe to the [Capawesome newsletter](https://capawesome.io/newsletter/){:target="_blank"} to stay updated on the latest news.
