Tutorial9 min read

Convert your Remix app to iOS and Android with Capacitor

Wrap a Remix app as native iOS and Android with Capacitor using SPA mode and static output, then wire up OtaKit to ship JS and CSS changes over the air in minutes.

Remix is a server-first framework, which makes “wrap it as a native app” a slightly more interesting question than for a plain SPA — a Capacitor app ships static assets to the device and has no Remix server running there. The answer is Remix's SPA mode. This guide covers taking a Remix app to iOS and Android with Capacitor, and shipping updates over the air with OtaKit.

The core adjustment: the device runs your client bundle only, and talks to your Remix backend over the network like any API. Use SPA mode so the build produces a client app that boots without a server render.

1. Enable SPA mode

Configure Remix's SPA mode so build emits a static client bundle. Your loaders and actions move to being called as API endpoints against your deployed backend, rather than server-rendering each request on the device.

2. Add Capacitor

npm install @capacitor/core @capacitor/cli
npx cap init
npm install @capacitor/ios @capacitor/android
npx cap add ios
npx cap add android

Point webDir at the SPA build output, then npm run build && npx cap sync.

3. Point data calls at your backend

On device there's no same-origin server, so every data call needs an absolute URL to your deployed Remix/API host, with CORS configured. This is the most common thing to get wrong — relative fetches that worked on the web silently fail on device.

4. Native polish + live updates

Then ship JS/CSS changes over the air:

otakit upload --release production

Since the device runs the client bundle, most of your iteration is client-side — exactly the code OTA updates ship. Backend changes deploy as usual on your server; client changes go over the air.

Where to go next

See the React guide for the SPA fundamentals and Setup to add OtaKit.

Related docs