macOS
Render Essence 2 and Expression 2 on a Mac with Apple silicon.
The iPhone and iPad Swift package, in a Mac app or from a terminal with swift run.
Before you start
No device, provisioning profile or entitlement is needed to try it from a terminal.
| You need | Expression 2 | Essence 2 |
|---|---|---|
| A Mac | Apple silicon, macOS 13 or newer | Apple silicon M3 or newer, macOS 26 or newer |
| Toolchain | Xcode 26 or newer (to build; Xcode 26 needs macOS 15.6 or newer) | the same |
| Credential | an API secret (Creator plan or higher) | the same |
| Disk | about 800 MB for the example: downloads plus the folder the engine unpacks them into | about 250 MB of downloads |
Install
In Xcode choose File → Add Package Dependencies… and paste https://gitlab.com/bithuman/sdk/homebrew-bithuman. In a Package.swift:
.package(url: "https://gitlab.com/bithuman/sdk/homebrew-bithuman", from: "2.20.5")
// then attach the product your target uses:
// .product(name: "Expression2", package: "homebrew-bithuman")
// .product(name: "Essence2Kit", package: "homebrew-bithuman")
// .product(name: "Essence2", package: "homebrew-bithuman")
The products:
| Product | Import | What it is | Deployment target |
|---|---|---|---|
Expression2 | import Expression2 | the Expression 2 engine with a Swift API | iOS 16 · macOS 13 |
Essence2Kit | import Essence2Kit | the Essence 2 engine with a Swift API; it includes Essence2 | iOS 26 · macOS 26 |
Essence2 | import Essence2 | the Essence 2 engine as a C library, for C, C++ and plugins | iOS 26 · macOS 26 |
Every product ships ios-arm64, ios-arm64-simulator (arm64 only) and macos-arm64.
Authenticate
The engines check an API secret when a session starts. Set BITHUMAN_API_SECRET in the scheme's environment, or pass it in code before you create an engine: Expression2Credential.set(secret) or Essence2Credential.set(secret) (Your API secret).
The scheme's environment is for local builds. A shipped app fetches its secret from your backend and keeps it in the Keychain (What a shipped app holds).
A Mac app built from Xcode’s App template turns on App Sandbox. Under Signing & Capabilities → App Sandbox, tick Outgoing Connections (Client), or the engines cannot check your secret.
Run your first avatar
The macOS Expression 2 example is one Swift file. Clone it, fetch the sample avatar, and run it:
git clone https://github.com/bithuman-product/bithuman-examples.git
cd bithuman-examples/swift/macos-expression2
./setup.sh # the wise-pup avatar, the shared engine and a speech clip
export BITHUMAN_API_SECRET="<your API secret>"
swift run -c release MacOSExpression2
Expected result
engine ready: 416x720, isReady=true
audio: 325451 samples, 20.34 s
generated 407 frames in … s -> out/first-frame.png
407 frames for 20.34 seconds of audio: one frame per 50 ms of speech. The first run prepares the engine for your Mac; keep Model/staged/ and later runs start faster.
The core of Sources/main.swift:
// excerpt: swift/macos-expression2/Sources/main.swift
let engine = try Expression2Engine.create(
avatarContainer: model.appendingPathComponent("agent.imx"),
sharedEngineContainer: model.appendingPathComponent("shared-engine.imx"),
stagingDir: model.appendingPathComponent("staged"))
// …
let started = Date()
engine.feed(samples)
engine.flushTail()
// …
var frames = 0, idleTicks = 0
while idleTicks < 100 {
var got = false
while let (frame, _) = engine.pull() {
if frames == 0 {
writePNG(frame, width: engine.width, height: engine.height,
to: out.appendingPathComponent("first-frame.png"))
}
frames += 1
got = true
}
if got { idleTicks = 0 } else { idleTicks += 1; usleep(50_000) }
}
Essence 2 on a Mac
Essence 2 needs an M3 or newer Mac on macOS 26. The same Essence2Kit calls as on the iPhone render a file from a terminal tool: download the avatar in code, set pacing = .unpaced, and take the frames as fast as they render.
// excerpt: a terminal tool (swift run) with the Essence2Kit product;
// samples is a 16 kHz mono clip as [Float].
import Essence2Kit
Essence2Credential.set(ProcessInfo.processInfo.environment["BITHUMAN_API_SECRET"] ?? "")
let imxURL = try await Essence2Download.identity(agentCode: "A52DHS2219") // sofia-ramirez
let engine = try await Essence2Engine.create(identity: imxURL) // waits until the engine is ready
engine.pacing = .unpaced // a file render: frames as fast as they render
engine.feed(samples) // [Float], 16 kHz mono
engine.flushTail() // that is the whole reply
var speech = 0
for await frame in engine.frames() {
if frame.isSpeech { speech += 1 } // frame.bgr: B, G, R bytes, width * height * 3
if frame.endsReply { break } // the reply is over; idle frames follow
}
print("\(engine.width)x\(engine.height): \(speech) frames for \(Double(samples.count) / 16_000) s of audio")
engine.shutdown()
Expected result
With the 15-second sample clip:
1080x1920: 375 frames for 14.997375 s of audio
25 frames a second at the avatar’s own size. The first create downloads the avatar and the engine’s runtime files, then keeps them in Caches and Application Support. The engine also prints its own diagnostic lines on stderr.
Capture details
Captured on an Apple M4 iMac (macOS) · Swift package 2.14.2 · wise-pup (Expression 2) · 2026-09-23.Performance
| Configuration | Essence 2 | Expression 2 |
|---|---|---|
| Apple M4 macOS · Swift package | 4.8× real timeApple M4 · Swift package 2.15.0 · measured 2026-09-24 | 8.8× real timeApple M4 · Swift package 2.15.0 · measured 2026-09-24 |
| Apple M4 macOS · CLI | 4.2× real timeApple M4 · CLI 2.8.1 · measured 2026-09-27 | 8.4× real timeApple M4 · CLI 2.8.1 · measured 2026-09-27 |
| Apple M4 macOS · Python | 6.9× real timeApple M4 · bithuman 2.11.12 · measured 2026-09-25 | 8.4× real timeApple M4 · bithuman 2.11.12 · measured 2026-09-25 |
Times real time: seconds of avatar video rendered per second. At 1.0× or more, an avatar holds a live conversation. Select a figure for its release and date. All configurations and how we measure.
This section moved: docs.bithuman.ai/platforms/macos#run-your-first-avatar
This section moved: docs.bithuman.ai/platforms/swift/app#integrate-into-your-app
This section moved: docs.bithuman.ai/platforms/swift/app#complete-example
This section moved: docs.bithuman.ai/platforms/swift/app#platform-notes
This section moved: docs.bithuman.ai/platforms/swift/troubleshooting#macos
This section moved: docs.bithuman.ai/platforms/swift/reference
