The Shopify mobile app has around 600 screens, and while all of them contribute to our merchants' mobile experience, not all of these screens are equally essential to their daily tasks.
There was no doubt that all critical screens needed to be built using native/React Native to deliver the best possible experience. However, applying the same approach to the rest of the screens proved to be extremely costly and massively slowed down our velocity.
Our challenge was clear: we needed an efficient way to deliver these less-critical screens within our mobile app, without having to build them separately for web and mobile.
WebViews seemed like the logical choice, but they typically fall short in delivering a good user experience—often feeling slow, disconnected, and noticeably out-of-place compared to true native screens.
Rather than accepting these limitations, we took it as an opportunity: could we reinvent WebViews to be faster, look better, and feel as seamless as native screens? This ambition led us to create Mobile Bridge—a framework specifically built to enhance WebViews, enabling web content to blend effortlessly with our mobile app.
In this post, we'll walk you through how we tackled the main issues of traditional WebViews—performance, appearance, and integration—and how Mobile Bridge became a game-changer in our mobile development strategy, even allowing us to accelerate the migration to React Native.
The Challenge with WebViews
Webviews are generally undesirable because users can tell they are not truly part of the app. They feel disconnected and slow, which creates a poor user experience.

To fix this, we started a project with three key goals:
- Make WebViews faster
- Make WebViews look native
- Make WebViews feel native
1. Making WebViews Faster 🚀
We started by figuring out why our WebViews felt so slow. It turned out that loading a new web page was slow mainly due to the authentication process. Each WebView had to bounce through several redirects just to authenticate, causing noticeable delays.
To speed things up, we came up with a simple solution: preloading and authenticating WebViews in the background as soon as the app opens.
To do this, we built native modules for both iOS and Android that can:
- Preload WebViews in the background (no more waiting!)
- Keep WebViews stored (cached) after they're used instead of throwing them away
- Reuse cached WebViews so users never experience unnecessary delays again!

This approach improved our WebView load times by ~6x—bringing the P75 down from 6 seconds to just 1.4 seconds, including both network latency and rendering time.

2. Making WebViews Look Native
With performance addressed, we turned our attention to improving the WebViews' look and feel, focusing on removing elements that made them seem out of place compared to native screens. Specifically, we tackled areas like:
- Zooming: We injected JavaScript to disable zooming.
- Text selection: We added CSS to remove text selection.
- Unnecessary UI elements: We hid parts of the admin interface that weren’t needed in WebViews, like the Title component and Page footer.
- Polaris Overrides: We adapted Polaris components to blend smoothly with the app’s native design.
Example: Disabling Zoom
Example: Preventing Text Selection
After these improvements, our WebViews got closer to matching native screens in look and feel, following consistent UX patterns.

3. Making WebViews Feel Native
To make WebViews truly feel native, Web and Mobile needed a simple way to communicate. They had to easily share data, keep track of what's happening, and react quickly—like knowing when a user navigates, finishes an action, or when something changes.
To achieve this, we built Mobile Bridge, a framework based on Shopify’s @remote-ui/rpc library. It allows smooth, two-way communication between web and mobile components.
Solving Page Titles and Page Actions
First, we tackled the Title Bar issue. Native screens show their titles and action buttons in the navigation bar, not on the page itself. To match this native pattern, we created APIs to set the title bar and actions in Mobile Bridge. Then, we modified the Polaris Page component to send its title and actions to Mobile Bridge. This lets us show them in the native navigation bar instead, instantly making WebViews feel more integrated.

Solving WebView Navigation
Another key challenge was navigation. Browsers usually reload the whole page when you click a link, but native apps push new screens onto a stack. Creating a new WebView for each screen would cause merchants to lose session data and dynamic content, resulting in a slow and frustrating experience.
To avoid this, we created a new component called TransportableView. It lets us move the existing WebView between screens without losing state or data. Because TransportableView can simply move a WebView instance from one screen to another, we don't lose any content or connections—even when navigating back!
Here's a simple example of TransportableView on iOS:
Handling Back Navigation
Moving the WebView between screens solves navigating forward because we always show a full-screen loader while the WebView moves to the new screen. This way, the user doesn't see content from the previous page appearing briefly on the new one. But what about navigating back? Without a solution, users could see an empty or broken screen when returning or previewing screens on iOS, disrupting the native feel we wanted.
To fix this, we take a quick snapshot of the WebView right before it moves. Then, when the user navigates back, they see a static image of exactly how the screen looked, preventing blank screens. As soon as the real WebView finishes loading on the new screen, we remove the snapshot.
Here's how we capture the snapshot on iOS:

Handling Modals the Native Way
Web modals typically appear on top of the current content, but in mobile apps, they're shown as separate screens with native transitions. To match this behavior, we present modals as native screens and transport the WebView, using the same strategy as with page transitions above.
The key difference: we customized the Polaris Modal component to delay rendering until the native animation completes. This keeps transitions smooth and avoids awkward flashes of content.

Taking It One Step Further
Our WebViews were massively better after these improvements, but we didn't stop there. To make the experience more seamless, we integrated existing native features directly into WebViews.
A great example of that is the Date Picker. Most of our analytics screens are WebViews, and selecting dates is a crucial part of viewing reports. The web-based Date Picker worked fine in browsers but didn't feel native in our app. Since we already had a native Date Picker component ready, we connected it directly through Mobile Bridge.
This blend of native and web elements creates a smoother, more enjoyable experience for users.

We've also enabled WebViews to seamlessly access native functionalities. Now, web content can trigger native screens directly and easily receive results back. Some current examples in our app include the "Add to Wallet" feature on both iOS and Android, and our native Barcode Scanner used within WebViews for inventory management. Merchants can quickly scan barcodes to fill out fields automatically, speeding up their workflows.

This hybrid approach allows us to quickly roll out web-based improvements while delivering richer, more native-feeling experiences for our users.
The Future of Mobile Bridge
Currently, Mobile Bridge enables web to trigger native UI elements, but these elements must be pre-implemented in the app. This slows down releases and prevents older app versions from benefiting from new features.
To solve this, we are experimenting with rendering Polaris components natively from web code using Shopify’s remote-dom.
This approach allows us to maintain business logic on the web while defining UI elements that are rendered natively in the app. As a result, we achieve greater flexibility and significantly improve the overall user experience of our hybrid app.
Here is an example of a prototype with this approach, can you guess what part is a WebView and what part is native?

Mobile Bridge: A Game Changer for Shopify
The improvements brought by Mobile Bridge have been so significant that Webviews have become a critical part of our mobile strategy. We are using them extensively to make important, but non-critical features available in the Shopify mobile app without building them twice—once on Web and once on mobile. We continue leveraging native and React Native for all critical features in the app to provide the best possible experience.
We've turned Mobile Bridge into a standalone library, and it is being integrated into other Shopify products like Balance, POS, and Shop. This means more apps can adopt this powerful hybrid approach and benefit from faster development cycles and improved user experience.
Mobile Bridge has completely changed how we approach web and mobile integration—giving us the flexibility and speed of web development while delivering a smooth, close to native experience. It is also freeing up a ton of engineering bandwidth that we are now able to apply to making all the critical native screens world-class.
Special thanks to Siavash Etemadieh for creating Mobile Bridge and to Lily Wu and Smit Patel for their contributions to make it better!