[ Documentation ]
Run a SwiftUI app

Run a SwiftUI app

This guide takes a SwiftUI app from a folder on your disk to a live iPhone in Peach, edits it while it runs, and ends with a screenshot and a recording you can send. It takes a few minutes plus the first compile. Swift support is in beta; see the iOS overview for what runs today.

1. Install Peach

If you have not installed Peach yet, follow the Quick start. You do not need Node.js, an Expo project or a running dev server for Swift.

2. Pick where your app compiles

Choose one:

  • +
    On your machine. Your source stays local. Set PEACH_SWIFT_ENDPOINT to the Swift distribution endpoint you received for the beta. The first run checks for the swift.org Swift 6.4.0 toolchain and its WebAssembly SDK, and if either is missing it prints the commands that install them. Run those, then run peach swift again.
  • +
    On Contrast. Sign in once with peach login and add --upload-source to the commands below. You need no Swift toolchain, and Peach uploads your app’s Swift sources to compile them.

3. Have a SwiftUI project

Use your own app, or make a new one:

terminal
mkdir Counter && cd Counter

Package.swift:

// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "Counter",
platforms: [.iOS(.v26)],
targets: [.executableTarget(name: "Counter", path: ".")]
)

App.swift:

import SwiftUI
@main
struct CounterApp: App {
var body: some Scene {
WindowGroup { ContentView() }
}
}
struct ContentView: View {
@State private var count = 0
var body: some View {
VStack(spacing: 16) {
Text("Tapped \(count) times").font(.title)
Button("Increment") { count += 1 }
.buttonStyle(.borderedProminent)
}
.padding()
}
}

An existing Xcode app works the same way: pass its .xcodeproj or .xcworkspace instead of the folder.

4. Run it

terminal
peach swift .

Or for an Xcode project:

terminal
peach swift ./MyApp.xcworkspace --scheme MyApp

Peach compiles the app, then opens it on an iPhone. The terminal shows where it compiles and the build it loaded:

Swift compile: /Users/you/Counter on this machine against …
Swift preview host: http://127.0.0.1:…
Swift artifact: …

The first compile builds every dependency and takes the longest. If it fails, read the end of the output. Peach lists any module your app imports that it does not provide, and the APIs it lacks with the files that use them.

Tap Increment a few times so the counter has state to keep.

5. Edit it live

Leave peach swift running and change the button title in App.swift:

Button("Add one") { count += 1 }

Save. The new title appears and the counter keeps its value. Because only a plain string literal in a view body changed, Peach applied it without compiling and printed Swift literals: 1 changed. A string with interpolation, such as the Text above it, compiles when you edit it.

Now make a structural change, for example add .italic() after .font(.title). Save. Peach compiles, prints a new Swift artifact, and swaps in the new code. The counter still keeps its value, because the view did not move in the tree.

Introduce a typo and save. The compiler error prints with its file, line and column, and Peach keeps watching. Fix it and save again; the app resumes with its state.

6. Try another device

Stop with Ctrl+C, then open on a different device:

terminal
peach swift . --device ipad-pro-13

Run peach swift . --device unknown to see the list of device models.

7. Capture and share

With the app running, use the same commands as any Peach app. In a second terminal:

terminal
peach screenshot --output counter.png
peach record --duration 8 --output counter.mp4

Send the PNG or MP4 to anyone; they need nothing installed to view them. For a hosted preview link, and how its visibility works, see Sharing. Hosted live links have not been verified with Swift apps yet, so open a link yourself before you send it, and send the recording when it matters.

8. Stop

Press Ctrl+C in the peach swift terminal. Peach closes the preview, the host and the file watcher it started.

Next steps

  • +
    Running Swift apps covers targets, schemes, build configurations and every flag.
  • +
    Testing runs flows against your running app.
  • +
    Device state sets location, permissions and other device conditions your app reads.