|
| 1 | +--- |
| 2 | +slug: build-ios-app-from-windows-capacitor-capgo-build |
| 3 | +title: Build an iOS App from Windows with Capacitor and Capgo Build |
| 4 | +description: >- |
| 5 | + Ship a real iOS binary from a Windows dev machine: wrap your web app with |
| 6 | + Capacitor, then use Capgo Build to compile, sign, and submit to TestFlight |
| 7 | + without owning a Mac. |
| 8 | +author: Martin Donadieu |
| 9 | +author_image_url: 'https://avatars.githubusercontent.com/u/4084527?v=4' |
| 10 | +author_url: 'https://x.com/martindonadieu' |
| 11 | +created_at: 2026-02-08T00:00:00.000Z |
| 12 | +updated_at: 2026-02-08T00:00:00.000Z |
| 13 | +head_image: /build_list.webp |
| 14 | +head_image_alt: Capgo Build jobs list |
| 15 | +keywords: Windows, iOS, Capacitor, Capgo Build, cloud build, TestFlight, App Store Connect, no Mac |
| 16 | +tag: Tutorial |
| 17 | +published: true |
| 18 | +locale: en |
| 19 | +next_blog: '' |
| 20 | +--- |
| 21 | + |
| 22 | +Building an iOS app traditionally means one thing: you need Xcode, and Xcode means macOS. That constraint is annoying if your whole team is on Windows or Linux, or if you just do not want to maintain a Mac build machine. |
| 23 | + |
| 24 | +The combo of **Capacitor** (to generate the native iOS project) and **Capgo Build** (to compile and sign it in the cloud) lets you do iOS builds and TestFlight submissions from a Windows workstation. |
| 25 | + |
| 26 | +This guide shows a pragmatic workflow that works well in teams: |
| 27 | + |
| 28 | +- Develop on Windows like a normal web project. |
| 29 | +- Keep `ios/` in your repo (so native state is reproducible). |
| 30 | +- Run `cap sync` locally (so your web build is copied into the iOS project). |
| 31 | +- Trigger an iOS cloud build with Capgo Build. |
| 32 | + |
| 33 | +## What You Actually Build Where |
| 34 | + |
| 35 | +There are two separate “builds” in a Capacitor app: |
| 36 | + |
| 37 | +- **Web build** (your JS/HTML/CSS): you do this locally on Windows. |
| 38 | +- **Native build** (Xcode archive, signing, upload): Capgo Build does this on Mac hardware in the cloud. |
| 39 | + |
| 40 | +This separation is the key: Capgo Build compiles the native project, but it expects your web assets to already be synced into `ios/`. |
| 41 | + |
| 42 | +## Prerequisites |
| 43 | + |
| 44 | +- A working Capacitor app (any framework is fine). |
| 45 | +- An Apple Developer account. |
| 46 | +- App Store Connect access for the app you want to upload (for TestFlight/App Store submission). |
| 47 | +- Your Capgo account and API token (`CAPGO_TOKEN`). |
| 48 | + |
| 49 | +## 1) Create or Prepare Your Capacitor App (Windows) |
| 50 | + |
| 51 | +If you already have a web app, skip to the Capacitor steps. |
| 52 | + |
| 53 | +Example with Vite: |
| 54 | + |
| 55 | +```bash |
| 56 | +bun create vite@latest my-app |
| 57 | +cd my-app |
| 58 | +bun install |
| 59 | +``` |
| 60 | + |
| 61 | +Build must produce static assets (for Vite this is `dist/` by default): |
| 62 | + |
| 63 | +```bash |
| 64 | +bun run build |
| 65 | +``` |
| 66 | + |
| 67 | +## 2) Add Capacitor and the iOS Platform |
| 68 | + |
| 69 | +Install Capacitor: |
| 70 | + |
| 71 | +```bash |
| 72 | +bun add @capacitor/core @capacitor/ios |
| 73 | +bun add -d @capacitor/cli |
| 74 | +``` |
| 75 | + |
| 76 | +Initialize and create the iOS platform folder: |
| 77 | + |
| 78 | +```bash |
| 79 | +bunx cap init |
| 80 | +bunx cap add ios |
| 81 | +``` |
| 82 | + |
| 83 | +At this point you will have an `ios/` directory. Commit it to git. Capgo Build compiles what is inside `ios/`, so you want it versioned and reproducible. |
| 84 | + |
| 85 | +## 3) Always Sync Web Assets into iOS Before Building |
| 86 | + |
| 87 | +Every time you change your web app, do this sequence on Windows: |
| 88 | + |
| 89 | +```bash |
| 90 | +bun run build |
| 91 | +bunx cap sync ios |
| 92 | +``` |
| 93 | + |
| 94 | +`cap sync` is what copies your built web assets into the native iOS project (the files Capgo Build will actually compile). |
| 95 | + |
| 96 | +## 4) Install and Authenticate the Capgo CLI |
| 97 | + |
| 98 | +Capgo Build is triggered via the Capgo CLI. With bun, use `bunx`: |
| 99 | + |
| 100 | +```bash |
| 101 | +bunx @capgo/cli@latest login |
| 102 | +``` |
| 103 | + |
| 104 | +Or set your token via env var in your shell/CI: |
| 105 | + |
| 106 | +```bash |
| 107 | +export CAPGO_TOKEN="your_api_key_here" |
| 108 | +``` |
| 109 | + |
| 110 | +## 5) Configure iOS Signing for Cloud Builds |
| 111 | + |
| 112 | +To build iOS you need signing material: |
| 113 | + |
| 114 | +- Apple Distribution certificate (`.p12`) and its password |
| 115 | +- Provisioning profile (`.mobileprovision`) |
| 116 | +- App Store Connect API key (`AuthKey_XXXXXX.p8`) and metadata (Key ID, Issuer ID, Team ID) |
| 117 | + |
| 118 | +If you still need to generate these files, follow the Capgo documentation: |
| 119 | + |
| 120 | +- [Managing Credentials](/docs/cli/cloud-build/credentials/) (what to save and how) |
| 121 | +- [How to Get iOS Certificates and Provisioning Profiles](/docs/cli/cloud-build/ios/#how-to-get-ios-certificates-and-provisioning-profiles) |
| 122 | + |
| 123 | +The easiest path is: create/export these once (often using any available Mac, a teammate, or a one-time rental), then reuse them from Windows for every subsequent build. |
| 124 | + |
| 125 | +Once you have the files locally, save them for Capgo Build: |
| 126 | + |
| 127 | +```bash |
| 128 | +bunx @capgo/cli@latest build credentials save \ |
| 129 | + --platform ios \ |
| 130 | + --certificate ./cert.p12 \ |
| 131 | + --p12-password "password" \ |
| 132 | + --provisioning-profile ./profile.mobileprovision \ |
| 133 | + --apple-key ./AuthKey.p8 \ |
| 134 | + --apple-key-id "KEY123" \ |
| 135 | + --apple-issuer-id "issuer-uuid" \ |
| 136 | + --apple-team-id "team-id" |
| 137 | +``` |
| 138 | + |
| 139 | +Tip: in CI, store the credential files base64-encoded as secrets, decode them at runtime, then run the same `build credentials save` command. |
| 140 | + |
| 141 | +## 6) Trigger an iOS Build from Windows |
| 142 | + |
| 143 | +From your app folder: |
| 144 | + |
| 145 | +```bash |
| 146 | +bun run build |
| 147 | +bunx cap sync ios |
| 148 | +bunx @capgo/cli@latest build com.example.app --platform ios --build-mode release |
| 149 | +``` |
| 150 | + |
| 151 | +You will see real-time logs in your terminal. If your App Store Connect key is configured, Capgo Build can submit the resulting build to TestFlight automatically. |
| 152 | + |
| 153 | +## 7) Iterate Fast: Live Updates for Web-Only Changes |
| 154 | + |
| 155 | +Capgo Build is for native changes: |
| 156 | + |
| 157 | +- adding/removing Capacitor plugins |
| 158 | +- changing native permissions |
| 159 | +- changing icons/splash |
| 160 | +- updating Capacitor |
| 161 | +- any Swift/Objective-C changes |
| 162 | + |
| 163 | +For day-to-day UI tweaks and JavaScript fixes, you generally want **Live Updates** (OTA), so you do not rebuild the native binary every time. |
| 164 | + |
| 165 | +A good team workflow is: |
| 166 | + |
| 167 | +- Use Live Updates for frequent web changes. |
| 168 | +- Use Capgo Build occasionally when native changes are needed. |
| 169 | + |
| 170 | +## Common Windows Pitfalls (and Fixes) |
| 171 | + |
| 172 | +- **Forgetting `cap sync`**: if your UI changes are missing in the iOS build, you likely built the web app but did not sync it into `ios/`. |
| 173 | +- **Not committing `ios/`**: Capgo Build compiles the native project. If the folder is not in git (or not in your build context), the build cannot reproduce your app. |
| 174 | +- **Plugin changes without native rebuild**: adding a plugin is a native change; plan a Capgo Build run (and a store submission) afterward. |
| 175 | + |
| 176 | +## Summary |
| 177 | + |
| 178 | +You cannot run Xcode on Windows, but you *can* ship iOS apps from Windows: |
| 179 | + |
| 180 | +1. Wrap your web app with Capacitor (`ios/` in your repo). |
| 181 | +2. Build web assets locally, then `cap sync`. |
| 182 | +3. Use Capgo Build to compile, sign, and submit your iOS binary from the CLI. |
0 commit comments