#swift #ffi #bindings #ios #mac


Generate FFI bindings for safe interop between Rust and Swift

6 releases

Uses new Rust 2021

new 0.1.5 Nov 26, 2021
0.1.4 Nov 26, 2021

#22 in macOS and iOS APIs

Download history 115/week @ 2021-11-23

115 downloads per month



Prolog 554 SLoC // 0.0% comments Rust 384 SLoC // 0.0% comments Swift 246 SLoC // 0.2% comments GNU Style Assembly 45 SLoC // 0.6% comments Alex 15 SLoC

swift-bridge Actions Status docs

Call Rust from Swift and vice versa.

swift-bridge generates code that helps you call Swift from Rust and vice versa.

swift-bridge takes inspiration from the awesome bridge module macro based approach pioneered by cxx.


# In your Cargo.toml

swift-bridge-build = "0.1"

swift-bridge = "0.1"


  • Put the library out to get feedback from bleeding edge users.

  • Continue to support more standard library types.

  • Continue to hone the API based on real usage feedback.

  • Figure out the safety story. What should be marked as safe vs. unsafe?

  • Focus on making usage of swift-bridge feel ergonomic.

  • Polish the documentation, examples and tutorials

  • Get to a point where we feel that there has been enough, real world production use and feedback for us to be confident that the user-facing API's won't need any breaking changes.

  • Release swift-bridge version 1.0

Quick Peek

TODO: Shorten this quick peak.. we don't need to include the build script, for example

Here's a quick peek at the Rust and Swift of a bridge that should give you a sense of how bindings look.

A more thorough walk through of swift-bridge can be found in the book (TODO: Link to GitHub pages).

// build.rs

fn main() {
    let bridges = vec!["src/lib.rs"];

    let out_dir = "./generated";

    for path in &bridges {
        println!("cargo:rerun-if-changed={}", path);
// lib.rs

mod ffi {
    extern "Rust" {
        type ARustStack;

        fn push (&mut self, val: u8);

        fn pop (&mut self) -> Option<u8>;
        fn as_slice (&self) -> &[u8];

        fn do_stuff(override: Option<u8>);

    extern "Swift" {
        type SwiftApiClient;

        fn new_with_timeout(timeout: u8) -> SwiftApiClient;

        #[swift_bridge(associated_to = FileSystemClient)]
        fn version () -> u32;

        fn set_timeout(&self, timeout: u8);

struct ARustStack(Vec<u8>);

impl ARustStack {
	fn push(&mut self, val: u8) {

	fn pop(&mut self) -> Option<u8> {

	fn as_slice(&self) -> &[u8] {

fn do_stuff(override: Option<u8>) {
    assert_eq!(SwiftApiClient::version(), 1);

    let client = SwiftApiClient::new_with_timeout(10);

	if let Some(override) = override {
// Swift

class SwiftApiClient {
    var timeout: UInt8

	init(timeout: UInt8) {
        self.timeout = timeout

	class func version() -> u32 {

	func setTimeout(timeout: UInt8) {
	    self.timeout = timeout

TODO's before open sourcing

We don't need to solve all of these, but we should at least create issues

  • Look up how to programatically set the linking settings and programatically set the run script. Our docs can recommend that as well as show how to manually set them

  • Remove #[no_mangle] since we're using link_name and export_name

Quick Peek

  • Write instructions on going from 0 to most basic iOS app

  • Add book chapter on setting up iOS app from scratch

  • Create examples dir example of iOS app

  • Create examples dir example of macOS app

Built-In Types

swift_bridge comes with support for a number of Rust and Swift standard library types.

name in Rust name in Swift notes
u8, i8, u16, i16... etc UInt8, Int8, UInt16, Int16 ... etc
bool Bool
String, &String, &mut String RustString
&str RustStr
Vec RustVec<T>
SwiftArray<T> Array<T> Not yet implemented
&[T] UnsafeBufferPointer<T>
&mut [T] UnsafeMutableBufferPointer<T> Not yet implemented
SwiftString String
Box Not yet implemented
[T; N] Not yet implemented
*const T UnsafePointer<T>
*mut T UnsafeMutablePointer<T>
Option<T> Optional<T> Currently only supported for primitive function return types.
Other places such as function arguments are not yet implemented.
Non primitive T is not yet implemented.
Result<T> Not yet implemented
Have a Rust standard library type in mind?
Open an issue!
Have a Swift standard library type in mind?
Open an issue!

To Test

To run the test suite.

# Clone the repository
git clone git@github.com:chinedufn/swift-bridge.git
cd swift-bridge

# Run tests
cargo test --all

See Also

  • Rust on iOS
    • A blog post by Mozilla that explains how to run Rust on iOS.


~23K SLoC