Introducing swift-ros2: a native Swift client library for ROS 2, now open source

:rocket: Excited to share that swift-ros2 — the wire layer that powers the Conduit iOS app:

is now available as a standalone open-source Swift package under Apache 2.0:

Since its App Store debut in January, Conduit peaked at #4 in the Developer Tools category and has been used by over 10,000 ROS 2 developers worldwide. The feedback from that community made it clear: the real value wasn’t only the iOS app — it was the Swift-side ROS 2 wire stack underneath it. So as part of this open-source release, that stack has been extracted, hardened, extended with a full CycloneDDS transport alongside the original Zenoh one, and ported to Linux — so any Swift project, on any Apple platform or on Ubuntu, can now speak ROS 2 natively without dragging in rcl/rclcpp.

Zenoh Pub/Sub between Mac and Ubuntu using swift-ros2:

DDS Pub/Sub between Mac and Ubuntu using swift-ros2:

:bullseye: What it does

swift-ros2 is a pure-Swift ROS 2 client library that publishes and subscribes directly at the wire level — no bridge, no RCL, no Python, no C++ glue in your app.

  • Dual transport, same API. Talk to rmw_zenoh_cpp via zenoh-pico, or to rmw_cyclonedds_cpp via CycloneDDS. Swap between them with a single config change.
  • Multi-distro wire format. Humble, Jazzy, Kilted, Rolling — all four are covered by the built-in wire codecs.
  • Pure-Swift XCDR v1 codec. Serialization is verified against golden-byte fixtures extracted from real ROS 2 traffic.
  • 20 built-in message types across sensor_msgs, geometry_msgs, std_msgs, audio_common_msgs, and tf2_msgs. Custom messages are a single ROS2Message conformance away.
  • Swift-native API. async/await, AsyncStream subscriptions, Sendable conformance, structured concurrency — the kind of API Swift developers actually want.

:laptop: Platforms

Platform Integration
iOS / iPadOS 16+ Pre-built xcframework via SPM
macOS 13+ Pre-built xcframework via SPM
Mac Catalyst 16+ Pre-built xcframework via SPM
visionOS 1.0+ Pre-built xcframework via SPM
Linux (Ubuntu 22.04 / 24.04, x86_64 + aarch64) swift build from source

CI exercises the full matrix — Swift 6.0.2 on Ubuntu with Humble (22.04), Jazzy (24.04), and Rolling (24.04), on both x86_64 and aarch64 — plus Xcode 16.2 on Apple Silicon:

:technologist: Publish in five lines

import SwiftROS2

let context = try await ROS2Context(
    transport: .zenoh(locator: "tcp/192.168.1.100:7447"),  // or: .ddsMulticast(domainId: 0)
    distro: .jazzy
)
let node = try await context.createNode(name: "sensor_node", namespace: "/macos")
let pub = try await node.createPublisher(Imu.self, topic: "imu")
try pub.publish(Imu(header: .now(frameId: "imu_link"), linearAcceleration: .init(x: 0, y: 0, z: 9.81)))

Switching to DDS is a one-line change to the transport: argument. Subscribers use the same Node API and expose an AsyncStream of typed messages.

Runnable talker / listener demos modeled on demo_nodes_cpp ship in Sources/Examples/ and interop directly with ros2 topic echo.

:white_check_mark: Today

  • Publishers and subscribers for both Zenoh and DDS transports
  • XCDR v1 serialize + deserialize
  • Jazzy / Humble / Kilted / Rolling wire codecs
  • 20 built-in message types
  • Custom message support via ROS2Message protocol

:motorway: Roadmap

  • Services (request/reply) and Actions (goal/feedback/result)
  • swift-ros2-gen — code generator for .msg / .srv / .action files, so any ROS 2 package’s interfaces can be consumed without hand-porting
  • Expanded message catalognav_msgs, visualization_msgs, and more
  • Continued hardening of the DDS subscriber path and wider distro coverage

:raising_hands: Who this is for

  • iOS / macOS / visionOS developers who want to ship ROS 2 apps without a sidecar bridge
  • Robotics teams looking for a lightweight Linux Swift client (agents, microservices, tooling)
  • Anyone who’s wanted a Swift-native way to speak to rmw_zenoh_cpp or rmw_cyclonedds_cpp

Issues, PRs, and wire-format war stories are all welcome!

2 Likes