Tutorial9 min read

Ship your Lovable (AI-built) app to iOS and Android with Capacitor

Built an app with Lovable, v0, or Bolt? Export the code, wrap it with Capacitor for the App Store and Google Play, and iterate fast with OtaKit over-the-air updates.

AI app builders like Lovable, v0, and Bolt make it fast to go from idea to a working web app. The gap they leave is the last mile: getting that app onto the App Store and Google Play, and iterating on it without a full redeploy each time. Capacitor and OtaKit close that gap.

Because these tools generate a standard web app — almost always React with Vite — you can wrap it natively with Capacitor and ship changes over the air. Here's the path.

Mental model: your AI-built app is a normal web app. Capacitor makes it a native app; OtaKit lets you keep vibe-coding and push each change straight to installed devices.

1. Get the code locally

Export or clone the project from your AI builder (Lovable, v0, and Bolt all let you download or connect a Git repo). You'll get a normal Node project — install dependencies and confirm it builds:

npm install
npm run build   # usually outputs to dist/ (Vite) or build/

Set a relative base so assets load from the native file:// origin. For a Vite project:

// vite.config.ts
export default defineConfig({ base: "./" });

2. Add Capacitor

npm install @capacitor/core
npm install -D @capacitor/cli

npx cap init "My App" com.example.myapp --web-dir dist

npm install @capacitor/ios @capacitor/android

npm run build
npx cap add ios
npx cap add android
npx cap sync

Open a platform (npx cap open ios) and you'll see your AI-built app running as a native app. For the deeper React-specific details — safe areas, routing — the React guide applies directly.

3. Add live updates with OtaKit

This is the part that matches how you built the app: fast iteration. Install the plugin and set your OtaKit app id:

npm install @otakit/capacitor-updater
npx cap sync
// capacitor.config.ts
const config: CapacitorConfig = {
  appId: "com.example.myapp",
  appName: "My App",
  webDir: "dist",
  plugins: {
    OtaKit: { appId: "YOUR_OTAKIT_APP_ID" },
  },
};
import { useEffect } from "react";
import { Capacitor } from "@capacitor/core";
import { OtaKit } from "@otakit/capacitor-updater";

// in your root component
useEffect(() => {
  if (Capacitor.isNativePlatform()) OtaKit.notifyAppReady();
}, []);
npm install -g @otakit/cli
otakit login

npm run build
otakit upload --release

After a one-time store submission with the plugin configured, every AI-generated change you build ships to installed devices with one command. Prompt a fix, build, upload — users get it on their next launch.

A note on AI-built apps and store review

AI builders can generate a lot of screens fast — make sure the app you submit is complete and does what its listing says. OTA is for iterating on that approved app, not for shipping a shell and filling it in later. See passing your first store review and what OTA can and can't change.

Where to go next

Start with the setup guide, then automate releases so every push ships.

Related docs