iOS Setup — Build & Run on Simulator
This guide walks through every step to get a Vue Native app building and running on the iOS Simulator, from prerequisites to hot reload.
Prerequisites
| Tool | Version | Install |
|---|---|---|
| Xcode | 15+ | Mac App Store |
| Xcode Command Line Tools | (bundled) | xcode-select --install |
| XcodeGen | 2.38+ | brew install xcodegen |
| Bun (or Node 18+) | 1.3+ | curl -fsSL https://bun.sh/install | bash |
| iOS Simulator | (bundled) | Included with Xcode |
Verify your environment:
xcode-select -p # /Applications/Xcode.app/Contents/Developer
swift --version # Apple Swift version 5.9+
xcodegen --version # XcodeGen 2.38+
bun --version # 1.3+
xcrun simctl list devices # lists available simulators
First-time Xcode install
After installing Xcode, open it once and accept the license. Then install the iOS Simulator runtime: Xcode > Settings > Platforms > iOS > Download.
Quick start (CLI)
The fastest path — the CLI handles everything:
# 1. Scaffold project
npx @thelacanians/vue-native-cli create my-app
cd my-app
bun install
# 2. Build JS bundle + run on simulator (all-in-one)
vue-native run ios
vue-native run ios does all of the following automatically:
- Runs
vite buildto producedist/vue-native-bundle.js - Generates the Xcode project from
ios/project.ymlvia XcodeGen - Builds the app with
xcodebuild - Boots the iOS Simulator
- Installs and launches the app
If you want to understand what happens under the hood (or run steps manually), read on.
Step-by-step (manual)
1. Create and scaffold
npx @thelacanians/vue-native-cli create my-app
cd my-app
bun install
This generates:
my-app/
app/ # Vue 3 source
main.ts
App.vue
pages/Home.vue
ios/ # Native Xcode project
project.yml # XcodeGen spec
Sources/
Info.plist
AppDelegate.swift
SceneDelegate.swift
dist/ # Built JS bundle (generated)
vite.config.ts
vue-native.config.ts
package.json
2. Build the JS bundle
bun run build
This runs Vite with the Vue Native plugin. It:
- Compiles
.vueSFCs via@vitejs/plugin-vue - Aliases
vueimports to@thelacanians/vue-native-runtime(the native renderer) - Outputs a single IIFE file:
dist/vue-native-bundle.js - Target: ES2020 (JavaScriptCore on iOS 16+ supports this)
3. Generate the Xcode project
cd ios
xcodegen generate
This reads project.yml and creates MyApp.xcodeproj. The project.yml declares:
- VueNativeCore as a remote Swift Package dependency (from GitHub)
- A Run Script build phase that copies
dist/vue-native-bundle.jsinto the.appbundle - Deployment target: iOS 16.0
- Swift 5.9
Tips
You only need to re-run xcodegen generate when you change project.yml (e.g. adding a new dependency or build phase). Source code changes don't require it.
4. Build the app
From the ios/ directory:
xcodebuild \
-project MyApp.xcodeproj \
-scheme MyApp \
-destination "platform=iOS Simulator,name=iPhone 16" \
-configuration Debug \
build
This:
- Resolves Swift Package Manager dependencies (VueNativeCore, FlexLayout)
- Compiles Swift sources (AppDelegate, SceneDelegate)
- Copies the JS bundle into the app via the Run Script phase
- Produces a
.appinDerivedData/
First build is slow
The first build downloads and compiles SPM dependencies (~1-2 min). Subsequent builds are incremental and much faster.
5. Boot the simulator
# List available simulators
xcrun simctl list devices available
# Boot a specific simulator
xcrun simctl boot "iPhone 16"
# Open the Simulator app
open -a Simulator
6. Install and launch
# Find the .app path
APP_PATH=$(find ~/Library/Developer/Xcode/DerivedData \
-name "MyApp.app" -path "*/Debug-iphonesimulator/*" | head -1)
# Install
xcrun simctl install booted "$APP_PATH"
# Launch
xcrun simctl launch booted com.vuenative.myapp
Your app should appear on the simulator.
Using Xcode directly
You can also build and run from Xcode's GUI:
- Open
ios/MyApp.xcodeproj - Select your scheme (top-left dropdown) and an iPhone simulator
- Press Cmd+R (or Product > Run)
Xcode handles the build, install, and launch. The console pane (Cmd+Shift+Y) shows [VueNative] log output.
Hot reload
Hot reload lets you edit .vue files and see changes instantly without rebuilding the native app.
Setup
Terminal 1 — Start the dev server:
bun run dev
This starts:
- Vite in watch mode (rebuilds
dist/vue-native-bundle.json every save) - A WebSocket server on
ws://localhost:8174
Terminal 2 — Run the app (first time only):
vue-native run ios
Or build from Xcode. Once the app is running, you don't need to rebuild — changes are pushed via WebSocket.
How it works
- You save
app/pages/Home.vue - Vite detects the change, rebuilds
vue-native-bundle.js - The dev server sends the new bundle over WebSocket
HotReloadManagerin the app receives itJSRuntimetears down the old JSContext, creates a new one, evaluates the new bundle- UI updates on screen
Enabling hot reload in your app
In the scaffolded project, the SceneDelegate subclasses VueNativeViewController which accepts a devServerURL:
class MyAppViewController: VueNativeViewController {
override var bundleName: String { "vue-native-bundle" }
#if DEBUG
override var devServerURL: URL? {
URL(string: "ws://localhost:8174")
}
#endif
}
The iOS Simulator shares the host network, so localhost works directly.
Debugging
Xcode console
All console.log() / console.error() calls from your Vue code appear in the Xcode console prefixed with [VueNative JS]:
[VueNative JS] App started
[VueNative JS] Navigated to /settings
Bridge operations are logged as:
[VueNative] createComponent VView (nodeId: 3)
[VueNative] setProp text="Hello" (nodeId: 5)
Error overlay
In debug builds, unhandled JS errors display a red overlay on screen with the error message and stack trace.
Checking the bundle loaded
If you see a white screen, verify the bundle is executing:
// Add to the top of app/main.ts
console.log('Bundle executing')
If you see the log, the bundle loaded. If not, check:
- The Run Script build phase copies
vue-native-bundle.jsinto the app bundle - The file exists:
bun run buildcompleted without errors
Useful simulator commands
# Take a screenshot
xcrun simctl io booted screenshot ~/Desktop/screenshot.png
# Open a URL (deep linking)
xcrun simctl openurl booted "myapp://settings"
# Reset simulator state
xcrun simctl erase "iPhone 16"
# View app container (logs, data)
xcrun simctl get_app_container booted com.vuenative.myapp data
Common issues
"No such module 'VueNativeCore'" — SPM hasn't resolved yet. In Xcode: File > Packages > Resolve Package Versions. If that fails, delete DerivedData:
rm -rf ~/Library/Developer/Xcode/DerivedData
"Signing requires a development team" — Open the project in Xcode, select the app target, go to Signing & Capabilities, and select your team (a free Apple ID works for simulator builds).
White screen — The most likely cause is the JS bundle not being copied into the app. Rebuild with bun run build, then rebuild the native app. Also check the Xcode console for [VueNative] errors.
Simulator won't boot — Reset it:
xcrun simctl shutdown all
xcrun simctl erase all
"Cannot find 'FlexLayout' in scope" — The FlexLayout SPM dependency failed to resolve. Delete DerivedData and the SPM cache, then rebuild:
rm -rf ~/Library/Developer/Xcode/DerivedData
rm -rf ~/Library/Caches/org.swift.swiftpm
See the Troubleshooting guide for more.