Command Palette

Search for a command to run...

backgroundradial

Wasmer Swift SDK for iOS and macOS

syrusakbary avatar
Syrus Akbary

Founder & CEO

Post cover image

Today we are extremely excited to welcome iOS (27 onwards) and macOS as new targets for the Wasmer SDK, with the Wasmer SDK Swift bindings.

You can now embed and run sandboxed programs in a Swift app: run Python, start a Node.js server, or process a video with FFmpeg, fully locally and without sending data out to any external server.

The API follows the same model as our Rust, Python and JavaScript SDKs: create a sandbox, load a package, and run a command.

A shell in your pocket

To show what this makes possible, we built WasmerShell: a native iOS terminal powered by the SDK and libghostty-vt. Pick an example, install its dependencies, and run it from the terminal.

image

The code for WasmerShell is fully available in the repo: https://github.com/wasmerio/wasmer-sdk/tree/main/swift/Examples/WasmerShell

The shell can run anything on your iOS device that Wasmer can:

  • Node.js: a small HTTP server, Express, or Next.js, powered by Edge.js.
  • Python: a standard-library HTTP server, Flask, Django, or FastAPI.
  • Command-line tools: FFmpeg for media processing and yt-dlp for downloading videos.

Each example starts with only the packages it needs. The plain Python and Node.js servers need no pip or npm dependencies. For a framework example, you install the dependencies yourself with pip or pnpm, just as you would on your laptop.

iOS meets WebAssembly

Running Wasmer sandboxes requires a WebAssembly runtime. To run WebAssembly fast you need a JIT compiler shipped with your app. However, bringing a JIT compiler to the iOS ecosystem is challenging (it’s only enabled when targeting Europe). As iOS already ships a fast WebAssembly engine inside WebKit… why not use it?

We build on the same WebAssembly approach as our Node.js bindings (using a WebAssembly engine that already exists rather than shipping a Wasm compiler or interpreter). On iOS, WASIX runs inside a hidden WKWebView, with a bridge to Swift for host services such as DNS, TCP networking and native filesystem access.

The SDK creates and manages the communication under the hood between the Wasm inside WKWebView and the native imports. This gives us three useful properties:

  • Reusing WebKit’s WebAssembly engine. We use the engine that ships with iOS instead of bundling another compiler, which helps on shipping a lean library.
  • Native host services. Sandboxed programs can make network requests and work with files through the SDK’s host integration (only when explicitly enabled)
  • A Swift interface. Your app uses async/await to run commands, read output and manage the sandbox. The JavaScript bridge stays inside the SDK.
  Your Swift app
       │  async/await
       ▼
  WasmerSDK (Swift) ◀──────────────┐
       │                          │ host calls (opt-in):
       │ callAsyncJavaScript      │ DNS · TCP · files
       ▼                          │ WKScriptMessageHandler
  Hidden WKWebView ────────────────┘
       │  JS bridge
       ▼
  WebKit Wasm engine (JIT + JSPI)
       │
       ▼
  WASIX sandbox: python · node · ffmpeg · clang

With this architecture, we have been able to run: Next.js, FastAPI, ffmpeg and even Clang fully on your iPhone.

The iOS backend requires iOS 27 or later, where WebKit provides the JSPI support it needs. It is currently experimental; the screenshots here are from the iOS simulator.

What about macOS?

On macOS, we use Wasmer’s native runtime, exposed to Swift through UniFFI.

No WebView is needed since we can simply run the Wasmer JIT. This backend supports macOS 12 and later, including Apple Silicon and Intel Macs.

image

Both platforms (iOS and macOS) use one SwiftPM library: WasmerSDK, and the same core API. Here is what running Python looks like inside an async Swift function:

import WasmerSDK

let wasmer = try Wasmer()
let sandbox = try await wasmer.sandboxes.create(
    packages: ["python/python@=3.13.20"]
)

let output = try await sandbox.command(
    "python", ["-c", "print('Hello from Swift!')"]
).run(timeout: 30)

print(try output.text())

try await sandbox.close()
try await wasmer.close()

You can also load your own Wasm or Wasmer package, stream a running command’s output, and read or write files through the sandbox. The complete demo includes cleanup when a command fails.

The shared API does not mean every optional feature is available on both backends yet. Use wasmer.capabilities to check features such as terminal support, directory mounts and HTTP previews.

Benchmarks

The new Swift SDK runs Node.js, Python and more programs at almost native speeds, even in your Phone.

For example, it gets 20,408 score in richards.js just ~5% below what you get in your native JS environment in a desktop.

Try it yourself

The code and examples are in the Wasmer SDK repository.

  • Follow the WasmerShell guide to build the iOS app with Xcode 27 and run the examples.
  • Follow the Swift SDK guide to add WasmerSDK to your app or run the native macOS demo.
  • Try the examples that are possible in iOS also in your browser at wasmer.sh.

We started Wasmer to make software run anywhere. With Swift support, that now includes the apps you build for iOS and macOS. We can’t wait to see what you create!

About the Author

Syrus Akbary is an enterpreneur and programmer. Specifically known for his contributions to the field of WebAssembly. He is the Founder and CEO of Wasmer, an innovative company that focuses on creating developer tools and infrastructure for running Wasm

Syrus Akbary avatar
Syrus Akbary

Founder & CEO

Read more
Post cover image

node.jsjavascriptruntimewasmer edge

Announcing Node.js Support on Wasmer Edge, powered by QuickJS

Syrus AkbaryAugust 31, 2026

craneliftllvmrisc-vruntimesinglepass

Wasmer 7

Syrus AkbaryJanuary 30, 2026

benchmarkllvmphpreleaseruntime

Announcing Wasmer 6.0 - closer to Native speeds!

Syrus AkbaryApril 25, 2025

releaseruntime

Introducing Wasmer 5.0

Syrus AkbaryOctober 29, 2024

Wasmer Swift SDK for iOS and macOS · Blog · Wasmer